2012-01-06 23:29:45 +01:00
|
|
|
/* ResidualVM - A 3D game interpreter
|
2008-06-13 14:57:47 +00:00
|
|
|
*
|
2012-01-06 23:29:45 +01:00
|
|
|
* ResidualVM is the legal property of its developers, whose names
|
2011-04-16 14:12:44 +02:00
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
2008-06-13 14:57:47 +00:00
|
|
|
* file distributed with this source distribution.
|
2006-04-02 14:20:45 +00:00
|
|
|
*
|
2012-12-19 23:15:43 +01:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
2014-04-05 18:18:42 +02:00
|
|
|
*
|
2012-12-19 23:15:43 +01:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
2006-04-02 14:20:45 +00:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2012-12-19 23:15:43 +01:00
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
2014-04-05 18:18:42 +02:00
|
|
|
*
|
2012-12-19 23:15:43 +01:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2006-04-02 14:20:45 +00:00
|
|
|
*
|
|
|
|
*/
|
2003-08-15 18:00:22 +00:00
|
|
|
|
2011-05-08 15:38:26 +02:00
|
|
|
#define FORBIDDEN_SYMBOL_EXCEPTION_fprintf
|
|
|
|
#define FORBIDDEN_SYMBOL_EXCEPTION_fgetc
|
2011-06-09 11:17:15 +02:00
|
|
|
#define FORBIDDEN_SYMBOL_EXCEPTION_stderr
|
|
|
|
#define FORBIDDEN_SYMBOL_EXCEPTION_stdin
|
2010-01-21 19:25:03 +00:00
|
|
|
|
2011-03-24 02:29:29 +08:00
|
|
|
#include "common/archive.h"
|
2012-01-31 21:39:34 +01:00
|
|
|
#include "common/debug-channels.h"
|
2009-10-05 08:33:46 +00:00
|
|
|
#include "common/file.h"
|
2012-03-26 20:12:00 -07:00
|
|
|
#include "common/foreach.h"
|
2011-04-10 21:59:04 +02:00
|
|
|
#include "common/fs.h"
|
2009-05-25 19:21:58 +00:00
|
|
|
#include "common/config-manager.h"
|
2015-09-08 16:58:22 +02:00
|
|
|
#include "common/translation.h"
|
2009-05-25 19:21:58 +00:00
|
|
|
|
2012-01-24 19:02:50 +01:00
|
|
|
#include "graphics/pixelbuffer.h"
|
2015-12-28 16:38:45 +01:00
|
|
|
#include "graphics/renderer.h"
|
2012-01-24 19:02:50 +01:00
|
|
|
|
2016-01-10 10:09:08 +01:00
|
|
|
#ifdef USE_OPENGL
|
|
|
|
#include "graphics/opengl/context.h"
|
|
|
|
#endif
|
|
|
|
|
2011-07-18 16:33:52 +02:00
|
|
|
#include "gui/error.h"
|
|
|
|
#include "gui/gui-manager.h"
|
2013-02-09 16:38:56 +01:00
|
|
|
#include "gui/message.h"
|
2011-07-18 16:33:52 +02:00
|
|
|
|
2015-08-14 15:16:40 +02:00
|
|
|
#include "image/png.h"
|
|
|
|
|
2009-05-25 19:21:58 +00:00
|
|
|
#include "engines/engine.h"
|
2020-10-02 19:14:19 +02:00
|
|
|
#include "engines/util.h"
|
2008-01-26 11:47:23 +00:00
|
|
|
|
2013-02-08 12:27:32 +01:00
|
|
|
#include "engines/grim/md5check.h"
|
|
|
|
#include "engines/grim/md5checkdialog.h"
|
2011-07-23 15:37:14 +02:00
|
|
|
#include "engines/grim/debug.h"
|
2009-05-24 19:13:58 +00:00
|
|
|
#include "engines/grim/grim.h"
|
|
|
|
#include "engines/grim/lua.h"
|
2011-10-12 17:42:40 +02:00
|
|
|
#include "engines/grim/lua_v1.h"
|
2012-11-12 23:07:32 +01:00
|
|
|
#include "engines/grim/emi/poolsound.h"
|
2013-12-04 00:55:14 +01:00
|
|
|
#include "engines/grim/emi/layer.h"
|
2009-05-24 19:13:58 +00:00
|
|
|
#include "engines/grim/actor.h"
|
2011-05-14 18:17:26 +02:00
|
|
|
#include "engines/grim/movie/movie.h"
|
2009-05-24 19:13:58 +00:00
|
|
|
#include "engines/grim/savegame.h"
|
|
|
|
#include "engines/grim/registry.h"
|
2009-05-25 19:21:58 +00:00
|
|
|
#include "engines/grim/resource.h"
|
|
|
|
#include "engines/grim/localize.h"
|
2011-05-21 18:18:27 +02:00
|
|
|
#include "engines/grim/gfx_base.h"
|
2011-05-13 17:55:14 -07:00
|
|
|
#include "engines/grim/bitmap.h"
|
|
|
|
#include "engines/grim/font.h"
|
|
|
|
#include "engines/grim/primitives.h"
|
2011-07-23 12:14:33 +02:00
|
|
|
#include "engines/grim/objectstate.h"
|
2011-09-19 16:53:08 +02:00
|
|
|
#include "engines/grim/set.h"
|
2012-01-22 14:14:15 +01:00
|
|
|
#include "engines/grim/sound.h"
|
2012-01-22 14:21:09 -05:00
|
|
|
#include "engines/grim/stuffit.h"
|
2013-02-04 16:37:34 +01:00
|
|
|
#include "engines/grim/debugger.h"
|
2009-05-25 19:21:58 +00:00
|
|
|
|
2009-05-24 19:13:58 +00:00
|
|
|
#include "engines/grim/imuse/imuse.h"
|
2014-07-18 14:37:29 +03:00
|
|
|
#include "engines/grim/emi/sound/emisound.h"
|
2004-04-20 17:49:12 +00:00
|
|
|
|
2011-10-13 20:25:50 +02:00
|
|
|
#include "engines/grim/lua/lua.h"
|
2011-03-21 05:16:27 +08:00
|
|
|
|
2009-05-25 06:49:57 +00:00
|
|
|
namespace Grim {
|
|
|
|
|
2014-05-29 15:35:46 -07:00
|
|
|
GrimEngine *g_grim = nullptr;
|
|
|
|
GfxBase *g_driver = nullptr;
|
2005-01-03 16:27:57 +00:00
|
|
|
int g_imuseState = -1;
|
2004-12-30 22:38:53 +00:00
|
|
|
|
2011-05-14 12:11:53 +02:00
|
|
|
GrimEngine::GrimEngine(OSystem *syst, uint32 gameFlags, GrimGameType gameType, Common::Platform platform, Common::Language language) :
|
2014-05-29 15:35:46 -07:00
|
|
|
Engine(syst), _currSet(nullptr), _selectedActor(nullptr), _pauseStartTime(0) {
|
2009-05-25 19:21:58 +00:00
|
|
|
g_grim = this;
|
|
|
|
|
2020-05-12 19:49:17 +02:00
|
|
|
setDebugger(new Debugger());
|
2011-03-24 22:04:40 +08:00
|
|
|
_gameType = gameType;
|
2011-05-14 12:11:53 +02:00
|
|
|
_gameFlags = gameFlags;
|
|
|
|
_gamePlatform = platform;
|
|
|
|
_gameLanguage = language;
|
2009-06-23 07:14:53 +00:00
|
|
|
|
2013-08-26 09:46:25 +02:00
|
|
|
if (getGameType() == GType_GRIM)
|
|
|
|
g_registry = new Registry();
|
|
|
|
else
|
2014-05-29 15:35:46 -07:00
|
|
|
g_registry = nullptr;
|
2013-08-26 09:46:25 +02:00
|
|
|
|
2014-05-29 15:35:46 -07:00
|
|
|
g_resourceloader = nullptr;
|
|
|
|
g_localizer = nullptr;
|
|
|
|
g_movie = nullptr;
|
|
|
|
g_imuse = nullptr;
|
2006-02-05 20:40:16 +00:00
|
|
|
|
2013-08-26 09:46:25 +02:00
|
|
|
//Set default settings
|
|
|
|
ConfMan.registerDefault("use_arb_shaders", true);
|
|
|
|
|
|
|
|
_showFps = ConfMan.getBool("show_fps");
|
|
|
|
|
2011-04-26 03:11:27 +08:00
|
|
|
_softRenderer = true;
|
2009-05-25 19:21:58 +00:00
|
|
|
|
2012-02-09 12:04:59 +01:00
|
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, 192);
|
2009-05-25 19:21:58 +00:00
|
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
|
|
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
|
|
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
|
|
|
|
|
2014-05-29 15:35:46 -07:00
|
|
|
_currSet = nullptr;
|
|
|
|
_selectedActor = nullptr;
|
2008-08-17 12:01:26 +00:00
|
|
|
_controlsEnabled = new bool[KEYCODE_EXTRA_LAST];
|
|
|
|
_controlsState = new bool[KEYCODE_EXTRA_LAST];
|
|
|
|
for (int i = 0; i < KEYCODE_EXTRA_LAST; i++) {
|
2004-12-09 23:55:43 +00:00
|
|
|
_controlsEnabled[i] = false;
|
2008-08-17 12:01:26 +00:00
|
|
|
_controlsState[i] = false;
|
|
|
|
}
|
2014-12-31 13:01:21 +01:00
|
|
|
_joyAxisPosition = new float[NUM_JOY_AXES];
|
|
|
|
for (int i = 0; i < NUM_JOY_AXES; i++) {
|
|
|
|
_joyAxisPosition[i] = 0;
|
|
|
|
}
|
2011-05-23 17:06:16 +02:00
|
|
|
_speechMode = TextAndVoice;
|
2008-08-01 18:27:11 +00:00
|
|
|
_textSpeed = 7;
|
2011-10-04 22:01:24 +02:00
|
|
|
_mode = _previousMode = NormalMode;
|
2005-08-13 16:25:51 +00:00
|
|
|
_flipEnable = true;
|
2013-08-26 09:46:25 +02:00
|
|
|
int speed = ConfMan.getInt("engine_speed");
|
2016-07-17 03:42:48 +00:00
|
|
|
if (speed == 0) {
|
|
|
|
_speedLimitMs = 0;
|
|
|
|
} else if (speed < 0 || speed > 100) {
|
2012-08-19 19:45:32 +02:00
|
|
|
_speedLimitMs = 1000 / 60;
|
2016-07-17 03:42:48 +00:00
|
|
|
ConfMan.setInt("engine_speed", 1000 / _speedLimitMs);
|
|
|
|
} else {
|
2008-08-17 05:36:41 +00:00
|
|
|
_speedLimitMs = 1000 / speed;
|
2016-07-17 03:42:48 +00:00
|
|
|
}
|
2014-05-29 15:35:46 -07:00
|
|
|
_listFilesIter = nullptr;
|
|
|
|
_savedState = nullptr;
|
2008-07-20 09:55:29 +00:00
|
|
|
_fps[0] = 0;
|
2011-07-17 18:17:07 +02:00
|
|
|
_iris = new Iris();
|
2012-02-24 17:11:55 +01:00
|
|
|
_buildActiveActorsList = false;
|
2005-03-20 16:48:26 +00:00
|
|
|
|
2012-01-27 11:47:28 -08:00
|
|
|
Color c(0, 0, 0);
|
2011-05-01 18:51:26 +02:00
|
|
|
|
2011-05-18 09:03:17 +08:00
|
|
|
_printLineDefaults.setX(0);
|
|
|
|
_printLineDefaults.setY(100);
|
|
|
|
_printLineDefaults.setWidth(0);
|
|
|
|
_printLineDefaults.setHeight(0);
|
|
|
|
_printLineDefaults.setFGColor(c);
|
2014-05-29 15:35:46 -07:00
|
|
|
_printLineDefaults.setFont(nullptr);
|
2011-05-18 09:03:17 +08:00
|
|
|
_printLineDefaults.setJustify(TextObject::LJUSTIFY);
|
|
|
|
|
|
|
|
_sayLineDefaults.setX(0);
|
|
|
|
_sayLineDefaults.setY(100);
|
|
|
|
_sayLineDefaults.setWidth(0);
|
|
|
|
_sayLineDefaults.setHeight(0);
|
|
|
|
_sayLineDefaults.setFGColor(c);
|
2014-05-29 15:35:46 -07:00
|
|
|
_sayLineDefaults.setFont(nullptr);
|
2011-05-18 19:31:58 +02:00
|
|
|
_sayLineDefaults.setJustify(TextObject::CENTER);
|
2011-05-18 09:03:17 +08:00
|
|
|
|
|
|
|
_blastTextDefaults.setX(0);
|
|
|
|
_blastTextDefaults.setY(200);
|
|
|
|
_blastTextDefaults.setWidth(0);
|
|
|
|
_blastTextDefaults.setHeight(0);
|
|
|
|
_blastTextDefaults.setFGColor(c);
|
2014-05-29 15:35:46 -07:00
|
|
|
_blastTextDefaults.setFont(nullptr);
|
2011-05-18 09:03:17 +08:00
|
|
|
_blastTextDefaults.setJustify(TextObject::LJUSTIFY);
|
2011-03-24 02:29:29 +08:00
|
|
|
|
2011-04-10 21:59:04 +02:00
|
|
|
const Common::FSNode gameDataDir(ConfMan.get("path"));
|
2011-12-16 14:48:42 +01:00
|
|
|
SearchMan.addSubDirectoryMatching(gameDataDir, "movies"); // Add 'movies' subdirectory for the demo
|
|
|
|
SearchMan.addSubDirectoryMatching(gameDataDir, "credits");
|
2015-03-22 13:07:38 +01:00
|
|
|
SearchMan.addSubDirectoryMatching(gameDataDir, "widescreen");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
|
|
|
Debug::registerDebugChannels();
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2009-05-17 08:12:05 +00:00
|
|
|
GrimEngine::~GrimEngine() {
|
2006-02-05 20:40:16 +00:00
|
|
|
delete[] _controlsEnabled;
|
2008-08-17 12:01:26 +00:00
|
|
|
delete[] _controlsState;
|
2014-12-31 13:01:21 +01:00
|
|
|
delete[] _joyAxisPosition;
|
2006-05-13 15:34:18 +00:00
|
|
|
|
2012-01-21 20:18:35 -08:00
|
|
|
clearPools();
|
2009-05-25 19:21:58 +00:00
|
|
|
|
2011-10-12 17:42:40 +02:00
|
|
|
delete LuaBase::instance();
|
2009-05-25 19:21:58 +00:00
|
|
|
if (g_registry) {
|
|
|
|
g_registry->save();
|
|
|
|
delete g_registry;
|
2014-05-29 15:35:46 -07:00
|
|
|
g_registry = nullptr;
|
2009-05-25 19:21:58 +00:00
|
|
|
}
|
2011-05-14 12:11:53 +02:00
|
|
|
delete g_movie;
|
2014-05-29 15:35:46 -07:00
|
|
|
g_movie = nullptr;
|
2009-05-25 19:21:58 +00:00
|
|
|
delete g_imuse;
|
2014-05-29 15:35:46 -07:00
|
|
|
g_imuse = nullptr;
|
2014-07-18 14:37:29 +03:00
|
|
|
delete g_emiSound;
|
|
|
|
g_emiSound = nullptr;
|
2012-01-25 20:35:58 -08:00
|
|
|
delete g_sound;
|
2014-05-29 15:35:46 -07:00
|
|
|
g_sound = nullptr;
|
2009-05-25 19:21:58 +00:00
|
|
|
delete g_localizer;
|
2014-05-29 15:35:46 -07:00
|
|
|
g_localizer = nullptr;
|
2009-05-25 19:21:58 +00:00
|
|
|
delete g_resourceloader;
|
2014-05-29 15:35:46 -07:00
|
|
|
g_resourceloader = nullptr;
|
2009-05-25 19:21:58 +00:00
|
|
|
delete g_driver;
|
2014-05-29 15:35:46 -07:00
|
|
|
g_driver = nullptr;
|
2011-07-17 18:17:07 +02:00
|
|
|
delete _iris;
|
2012-01-31 21:39:34 +01:00
|
|
|
|
2013-08-26 09:46:25 +02:00
|
|
|
ConfMan.flushToDisk();
|
2012-01-31 21:39:34 +01:00
|
|
|
DebugMan.clearAllDebugChannels();
|
2014-06-21 00:08:10 -07:00
|
|
|
|
|
|
|
g_grim = nullptr;
|
2009-05-25 19:21:58 +00:00
|
|
|
}
|
|
|
|
|
2012-01-21 20:18:35 -08:00
|
|
|
void GrimEngine::clearPools() {
|
|
|
|
Set::getPool().deleteObjects();
|
|
|
|
Actor::getPool().deleteObjects();
|
|
|
|
PrimitiveObject::getPool().deleteObjects();
|
|
|
|
TextObject::getPool().deleteObjects();
|
|
|
|
Bitmap::getPool().deleteObjects();
|
|
|
|
Font::getPool().deleteObjects();
|
|
|
|
ObjectState::getPool().deleteObjects();
|
|
|
|
|
2014-05-29 15:35:46 -07:00
|
|
|
_currSet = nullptr;
|
2012-01-21 20:18:35 -08:00
|
|
|
}
|
|
|
|
|
2013-07-07 12:54:01 -07:00
|
|
|
LuaBase *GrimEngine::createLua() {
|
|
|
|
return new Lua_V1();
|
|
|
|
}
|
|
|
|
|
2017-08-26 22:24:18 +02:00
|
|
|
GfxBase *GrimEngine::createRenderer(int screenW, int screenH, bool fullscreen) {
|
2015-12-28 16:38:45 +01:00
|
|
|
Common::String rendererConfig = ConfMan.get("renderer");
|
|
|
|
Graphics::RendererType desiredRendererType = Graphics::parseRendererTypeCode(rendererConfig);
|
|
|
|
Graphics::RendererType matchingRendererType = Graphics::getBestMatchingAvailableRendererType(desiredRendererType);
|
2013-02-04 12:46:42 +01:00
|
|
|
|
2016-01-10 10:09:08 +01:00
|
|
|
_softRenderer = matchingRendererType == Graphics::kRendererTypeTinyGL;
|
2020-10-02 19:14:19 +02:00
|
|
|
initGraphics3d(screenW, screenH, fullscreen, !_softRenderer);
|
2016-01-10 10:09:08 +01:00
|
|
|
|
|
|
|
#if defined(USE_OPENGL)
|
|
|
|
// Check the OpenGL context actually supports shaders
|
|
|
|
if (matchingRendererType == Graphics::kRendererTypeOpenGLShaders && !OpenGLContext.shadersSupported) {
|
|
|
|
matchingRendererType = Graphics::kRendererTypeOpenGL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-12-28 16:38:45 +01:00
|
|
|
if (matchingRendererType != desiredRendererType && desiredRendererType != Graphics::kRendererTypeDefault) {
|
|
|
|
// Display a warning if unable to use the desired renderer
|
|
|
|
warning("Unable to create a '%s' renderer", rendererConfig.c_str());
|
2013-02-04 12:46:42 +01:00
|
|
|
}
|
|
|
|
|
2016-01-10 10:09:08 +01:00
|
|
|
GfxBase *renderer = nullptr;
|
2015-12-28 16:38:45 +01:00
|
|
|
#if defined(USE_GLES2) || defined(USE_OPENGL_SHADERS)
|
|
|
|
if (matchingRendererType == Graphics::kRendererTypeOpenGLShaders) {
|
2016-01-10 10:09:08 +01:00
|
|
|
renderer = CreateGfxOpenGLShader();
|
2015-12-28 16:38:45 +01:00
|
|
|
}
|
2015-12-28 17:10:11 +01:00
|
|
|
#endif
|
|
|
|
#if defined(USE_OPENGL) && !defined(USE_GLES2)
|
2015-12-28 16:38:45 +01:00
|
|
|
if (matchingRendererType == Graphics::kRendererTypeOpenGL) {
|
2016-01-10 10:09:08 +01:00
|
|
|
renderer = CreateGfxOpenGL();
|
2015-12-28 16:38:45 +01:00
|
|
|
}
|
2013-02-04 12:46:42 +01:00
|
|
|
#endif
|
2015-12-28 16:38:45 +01:00
|
|
|
if (matchingRendererType == Graphics::kRendererTypeTinyGL) {
|
2016-01-10 10:09:08 +01:00
|
|
|
renderer = CreateGfxTinyGL();
|
2013-02-04 12:46:42 +01:00
|
|
|
}
|
2015-12-28 16:38:45 +01:00
|
|
|
|
2016-01-10 10:09:08 +01:00
|
|
|
if (!renderer) {
|
|
|
|
error("Unable to create a '%s' renderer", rendererConfig.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
renderer->setupScreen(screenW, screenH, fullscreen);
|
2016-07-12 06:08:21 +02:00
|
|
|
renderer->loadEmergFont();
|
2016-01-10 10:09:08 +01:00
|
|
|
return renderer;
|
2013-02-04 12:46:42 +01:00
|
|
|
}
|
|
|
|
|
2013-08-29 18:18:05 +02:00
|
|
|
const char *GrimEngine::getUpdateFilename() {
|
2013-08-29 23:05:49 +02:00
|
|
|
if (!(getGameFlags() & ADGF_DEMO))
|
2013-08-29 18:18:05 +02:00
|
|
|
return "gfupd101.exe";
|
2013-08-29 23:05:49 +02:00
|
|
|
else
|
2014-05-29 15:35:46 -07:00
|
|
|
return nullptr;
|
2013-08-29 18:18:05 +02:00
|
|
|
}
|
|
|
|
|
2009-05-25 19:21:58 +00:00
|
|
|
Common::Error GrimEngine::run() {
|
2012-01-22 14:21:09 -05:00
|
|
|
// Try to see if we have the EMI Mac installer present
|
|
|
|
// Currently, this requires the data fork to be standalone
|
2014-09-17 21:14:22 +02:00
|
|
|
if (getGameType() == GType_MONKEY4) {
|
|
|
|
if (SearchMan.hasFile("Monkey Island 4 Installer")) {
|
|
|
|
StuffItArchive *archive = new StuffItArchive();
|
|
|
|
|
|
|
|
if (archive->open("Monkey Island 4 Installer"))
|
|
|
|
SearchMan.add("Monkey Island 4 Installer", archive, 0, true);
|
|
|
|
else
|
|
|
|
delete archive;
|
|
|
|
}
|
|
|
|
if (SearchMan.hasFile("EFMI Installer")) {
|
|
|
|
StuffItArchive *archive = new StuffItArchive();
|
|
|
|
|
|
|
|
if (archive->open("EFMI Installer"))
|
|
|
|
SearchMan.add("EFMI Installer", archive, 0, true);
|
|
|
|
else
|
|
|
|
delete archive;
|
2012-01-22 14:21:09 -05:00
|
|
|
|
2014-09-17 21:14:22 +02:00
|
|
|
}
|
2012-01-22 14:21:09 -05:00
|
|
|
}
|
|
|
|
|
2013-02-08 12:27:32 +01:00
|
|
|
ConfMan.registerDefault("check_gamedata", true);
|
|
|
|
if (ConfMan.getBool("check_gamedata")) {
|
|
|
|
MD5CheckDialog d;
|
2013-02-09 16:38:56 +01:00
|
|
|
if (!d.runModal()) {
|
2020-09-03 02:01:03 +02:00
|
|
|
Common::U32String confirmString = Common::U32String::format(_(
|
2015-09-08 16:58:22 +02:00
|
|
|
"ResidualVM found some problems with your game data files.\n"
|
|
|
|
"Running ResidualVM nevertheless may cause game bugs or even crashes.\n"
|
|
|
|
"Do you still want to run %s?"),
|
2020-09-03 02:01:03 +02:00
|
|
|
GType_MONKEY4 == getGameType() ? "Escape From Monkey Island" : "Grim Fandango"
|
2015-09-08 16:58:22 +02:00
|
|
|
);
|
|
|
|
GUI::MessageDialog msg(confirmString, _("Yes"), _("No"));
|
2013-02-09 16:38:56 +01:00
|
|
|
if (!msg.runModal()) {
|
|
|
|
return Common::kUserCanceled;
|
|
|
|
}
|
|
|
|
}
|
2013-02-08 12:27:32 +01:00
|
|
|
|
|
|
|
ConfMan.setBool("check_gamedata", false);
|
2014-02-23 20:50:56 +01:00
|
|
|
ConfMan.flushToDisk();
|
2013-02-08 12:27:32 +01:00
|
|
|
}
|
|
|
|
|
2009-05-26 06:27:47 +00:00
|
|
|
g_resourceloader = new ResourceLoader();
|
2011-10-04 18:47:03 +02:00
|
|
|
bool demo = getGameFlags() & ADGF_DEMO;
|
2011-05-14 12:11:53 +02:00
|
|
|
if (getGameType() == GType_GRIM)
|
2011-10-04 18:47:03 +02:00
|
|
|
g_movie = CreateSmushPlayer(demo);
|
2011-05-14 12:11:53 +02:00
|
|
|
else if (getGameType() == GType_MONKEY4) {
|
|
|
|
if (_gamePlatform == Common::kPlatformPS2)
|
2011-05-14 18:17:26 +02:00
|
|
|
g_movie = CreateMpegPlayer();
|
2011-05-14 12:11:53 +02:00
|
|
|
else
|
2011-10-04 18:47:03 +02:00
|
|
|
g_movie = CreateBinkPlayer(demo);
|
2011-05-12 00:55:42 +08:00
|
|
|
}
|
2014-07-19 15:10:46 +03:00
|
|
|
if (getGameType() == GType_GRIM) {
|
2014-07-18 14:37:29 +03:00
|
|
|
g_imuse = new Imuse(20, demo);
|
2014-07-19 15:10:46 +03:00
|
|
|
g_emiSound = nullptr;
|
|
|
|
} else if (getGameType() == GType_MONKEY4) {
|
2014-07-18 14:37:29 +03:00
|
|
|
g_emiSound = new EMISound(20);
|
2014-07-19 15:10:46 +03:00
|
|
|
g_imuse = nullptr;
|
|
|
|
}
|
2012-01-25 20:35:58 -08:00
|
|
|
g_sound = new SoundPlayer();
|
2009-05-26 06:27:47 +00:00
|
|
|
|
2017-08-26 22:24:18 +02:00
|
|
|
bool fullscreen = ConfMan.getBool("fullscreen");
|
|
|
|
g_driver = createRenderer(640, 480, fullscreen);
|
2009-05-25 19:21:58 +00:00
|
|
|
|
2012-01-22 14:21:09 -05:00
|
|
|
if (getGameType() == GType_MONKEY4 && SearchMan.hasFile("AMWI.m4b")) {
|
2014-10-01 02:19:06 +02:00
|
|
|
// Play EMI Mac Aspyr logo
|
|
|
|
playAspyrLogo();
|
2012-01-22 14:21:09 -05:00
|
|
|
}
|
|
|
|
|
2014-05-29 15:35:46 -07:00
|
|
|
Bitmap *splash_bm = nullptr;
|
2011-05-14 12:11:53 +02:00
|
|
|
if (!(_gameFlags & ADGF_DEMO) && getGameType() == GType_GRIM)
|
2012-02-02 09:34:53 -08:00
|
|
|
splash_bm = Bitmap::create("splash.bm");
|
2011-07-29 03:48:17 +02:00
|
|
|
else if ((_gameFlags & ADGF_DEMO) && getGameType() == GType_MONKEY4)
|
2012-02-02 09:34:53 -08:00
|
|
|
splash_bm = Bitmap::create("splash.til");
|
2012-01-14 13:21:43 +01:00
|
|
|
else if (getGamePlatform() == Common::kPlatformPS2 && getGameType() == GType_MONKEY4)
|
2012-02-02 09:34:53 -08:00
|
|
|
splash_bm = Bitmap::create("load.tga");
|
2009-05-25 19:21:58 +00:00
|
|
|
|
|
|
|
g_driver->clearScreen();
|
|
|
|
|
2014-05-29 15:35:46 -07:00
|
|
|
if (splash_bm != nullptr)
|
2011-07-29 03:48:17 +02:00
|
|
|
splash_bm->draw();
|
2012-02-12 21:39:19 +01:00
|
|
|
|
2012-03-09 15:17:41 +01:00
|
|
|
// This flipBuffer() may make the OpenGL renderer show garbage instead of the splash,
|
|
|
|
// while the TinyGL renderer needs it.
|
|
|
|
if (_softRenderer)
|
|
|
|
g_driver->flipBuffer();
|
2011-08-24 16:51:44 +02:00
|
|
|
|
2013-07-07 12:54:01 -07:00
|
|
|
LuaBase *lua = createLua();
|
2009-05-25 19:21:58 +00:00
|
|
|
|
2011-10-12 17:42:40 +02:00
|
|
|
lua->registerOpcodes();
|
|
|
|
lua->registerLua();
|
2012-03-03 12:23:45 +01:00
|
|
|
|
2015-01-18 16:37:51 +01:00
|
|
|
// One version of the demo doesn't set the demo flag in scripts.
|
|
|
|
if (getGameType() == GType_GRIM && _gameFlags & ADGF_DEMO) {
|
|
|
|
lua->forceDemo();
|
|
|
|
}
|
|
|
|
|
2013-07-01 22:30:27 +02:00
|
|
|
//Initialize Localizer first. In system-script are already localizeable Strings
|
2012-04-06 12:55:53 -07:00
|
|
|
g_localizer = new Localizer();
|
2013-07-01 22:30:27 +02:00
|
|
|
lua->loadSystemScript();
|
2011-10-12 17:42:40 +02:00
|
|
|
lua->boot();
|
2009-05-25 19:21:58 +00:00
|
|
|
|
2011-05-17 20:48:58 -07:00
|
|
|
_savegameLoadRequest = false;
|
|
|
|
_savegameSaveRequest = false;
|
|
|
|
|
|
|
|
// Load game from specified slot, if any
|
|
|
|
if (ConfMan.hasKey("save_slot")) {
|
2012-03-26 20:28:31 -07:00
|
|
|
loadGameState(ConfMan.getInt("save_slot"));
|
2011-05-17 20:48:58 -07:00
|
|
|
}
|
|
|
|
|
2011-10-04 22:01:24 +02:00
|
|
|
g_grim->setMode(NormalMode);
|
2013-07-07 21:11:34 -07:00
|
|
|
delete splash_bm;
|
2009-05-25 19:21:58 +00:00
|
|
|
g_grim->mainLoop();
|
|
|
|
|
|
|
|
return Common::kNoError;
|
2006-02-05 20:40:16 +00:00
|
|
|
}
|
|
|
|
|
2014-10-01 02:19:06 +02:00
|
|
|
void GrimEngine::playAspyrLogo() {
|
|
|
|
// A trimmed down version of the code found in mainloop
|
|
|
|
// for the purpose of playing the Aspyr-logo.
|
|
|
|
// The reason for this, is that the logo needs a different
|
|
|
|
// codec than all the other videos (which are Bink).
|
|
|
|
// Code is provided to keep within the fps-limit, as well as to
|
|
|
|
// allow for pressing ESC to skip the movie.
|
|
|
|
MoviePlayer *defaultPlayer = g_movie;
|
|
|
|
g_movie = CreateQuickTimePlayer();
|
|
|
|
g_movie->play("AMWI.m4b", false, 0, 0);
|
|
|
|
setMode(SmushMode);
|
|
|
|
while (g_movie->isPlaying()) {
|
|
|
|
_doFlip = true;
|
|
|
|
uint32 startTime = g_system->getMillis();
|
|
|
|
|
|
|
|
updateDisplayScene();
|
|
|
|
if (_doFlip) {
|
|
|
|
doFlip();
|
|
|
|
}
|
|
|
|
// Process events to allow the user to skip the logo.
|
|
|
|
Common::Event event;
|
|
|
|
while (g_system->getEventManager()->pollEvent(event)) {
|
|
|
|
// Ignore everything but ESC when movies are playing
|
|
|
|
Common::EventType type = event.type;
|
|
|
|
if (type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) {
|
|
|
|
g_movie->stop();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32 endTime = g_system->getMillis();
|
|
|
|
if (startTime > endTime)
|
|
|
|
continue;
|
|
|
|
uint32 diffTime = endTime - startTime;
|
|
|
|
if (_speedLimitMs == 0)
|
|
|
|
continue;
|
|
|
|
if (diffTime < _speedLimitMs) {
|
|
|
|
uint32 delayTime = _speedLimitMs - diffTime;
|
|
|
|
g_system->delayMillis(delayTime);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
delete g_movie;
|
|
|
|
setMode(NormalMode);
|
|
|
|
g_movie = defaultPlayer;
|
|
|
|
}
|
|
|
|
|
2012-03-26 20:28:31 -07:00
|
|
|
Common::Error GrimEngine::loadGameState(int slot) {
|
|
|
|
assert(slot >= 0);
|
2013-07-09 21:12:55 +02:00
|
|
|
if (getGameType() == GType_MONKEY4) {
|
2015-02-10 15:12:15 -05:00
|
|
|
if (getGamePlatform() == Common::kPlatformPS2) {
|
|
|
|
_savegameFileName = Common::String::format("efmi%03d.ps2", slot);
|
|
|
|
} else {
|
|
|
|
_savegameFileName = Common::String::format("efmi%03d.gsv", slot);
|
|
|
|
}
|
2013-06-27 00:07:57 +02:00
|
|
|
} else {
|
2013-07-09 21:12:55 +02:00
|
|
|
_savegameFileName = Common::String::format("grim%02d.gsv", slot);
|
2013-06-27 00:07:57 +02:00
|
|
|
}
|
2012-03-26 20:28:31 -07:00
|
|
|
_savegameLoadRequest = true;
|
|
|
|
return Common::kNoError;
|
|
|
|
}
|
|
|
|
|
2009-05-31 16:09:21 +00:00
|
|
|
void GrimEngine::handlePause() {
|
2011-10-13 20:25:50 +02:00
|
|
|
if (!LuaBase::instance()->callback("pauseHandler")) {
|
2009-05-31 16:09:21 +00:00
|
|
|
error("handlePause: invalid handler");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GrimEngine::handleExit() {
|
2011-10-13 20:25:50 +02:00
|
|
|
if (!LuaBase::instance()->callback("exitHandler")) {
|
2009-05-31 16:09:21 +00:00
|
|
|
error("handleExit: invalid handler");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GrimEngine::handleUserPaint() {
|
2011-10-13 20:25:50 +02:00
|
|
|
if (!LuaBase::instance()->callback("userPaintHandler")) {
|
2009-05-31 16:09:21 +00:00
|
|
|
error("handleUserPaint: invalid handler");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-13 20:25:50 +02:00
|
|
|
void GrimEngine::cameraChangeHandle(int prev, int next) {
|
|
|
|
LuaObjects objects;
|
|
|
|
objects.add(prev);
|
|
|
|
objects.add(next);
|
|
|
|
LuaBase::instance()->callback("camChangeHandler", objects);
|
|
|
|
}
|
2008-08-17 12:01:26 +00:00
|
|
|
|
2011-10-13 20:25:50 +02:00
|
|
|
void GrimEngine::cameraPostChangeHandle(int num) {
|
|
|
|
LuaObjects objects;
|
|
|
|
objects.add(num);
|
|
|
|
LuaBase::instance()->callback("postCamChangeHandler", objects);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GrimEngine::savegameCallback() {
|
|
|
|
if (!LuaBase::instance()->callback("saveGameCallback")) {
|
|
|
|
error("GrimEngine::savegameCallback: invalid handler");
|
|
|
|
}
|
2005-04-05 13:50:54 +00:00
|
|
|
}
|
|
|
|
|
2009-05-17 08:12:05 +00:00
|
|
|
void GrimEngine::handleDebugLoadResource() {
|
2014-05-29 15:35:46 -07:00
|
|
|
void *resource = nullptr;
|
2005-08-13 13:35:43 +00:00
|
|
|
int c, i = 0;
|
2013-04-21 15:25:22 +02:00
|
|
|
char buf[513];
|
2005-08-13 13:35:43 +00:00
|
|
|
|
|
|
|
// Tool for debugging the loading of a particular resource without
|
|
|
|
// having to actually make it all the way to it in the game
|
|
|
|
fprintf(stderr, "Enter resource to load (extension specifies type): ");
|
|
|
|
while (i < 512 && (c = fgetc(stdin)) != EOF && c != '\n')
|
|
|
|
buf[i++] = c;
|
|
|
|
|
|
|
|
buf[i] = '\0';
|
2009-05-12 14:32:43 +00:00
|
|
|
if (strstr(buf, ".key"))
|
2005-08-13 13:35:43 +00:00
|
|
|
resource = (void *)g_resourceloader->loadKeyframe(buf);
|
|
|
|
else if (strstr(buf, ".zbm") || strstr(buf, ".bm"))
|
2012-02-02 09:34:53 -08:00
|
|
|
resource = (void *)Bitmap::create(buf);
|
2005-08-13 13:35:43 +00:00
|
|
|
else if (strstr(buf, ".cmp"))
|
|
|
|
resource = (void *)g_resourceloader->loadColormap(buf);
|
|
|
|
else if (strstr(buf, ".cos"))
|
2014-06-09 18:41:01 +03:00
|
|
|
resource = (void *)g_resourceloader->loadCostume(buf, nullptr, nullptr);
|
2005-08-13 13:35:43 +00:00
|
|
|
else if (strstr(buf, ".lip"))
|
2009-04-21 18:04:24 +00:00
|
|
|
resource = (void *)g_resourceloader->loadLipSync(buf);
|
2005-08-13 13:35:43 +00:00
|
|
|
else if (strstr(buf, ".snm"))
|
2011-05-14 12:11:53 +02:00
|
|
|
resource = (void *)g_movie->play(buf, false, 0, 0);
|
2005-08-13 13:35:43 +00:00
|
|
|
else if (strstr(buf, ".wav") || strstr(buf, ".imu")) {
|
2014-07-18 14:37:29 +03:00
|
|
|
if (g_imuse)
|
|
|
|
g_imuse->startSfx(buf);
|
2005-08-13 13:35:43 +00:00
|
|
|
resource = (void *)1;
|
|
|
|
} else if (strstr(buf, ".mat")) {
|
|
|
|
CMap *cmap = g_resourceloader->loadColormap("item.cmp");
|
2009-05-31 07:33:18 +00:00
|
|
|
warning("Default colormap applied to resources loaded in this fashion");
|
2014-06-17 21:58:21 -04:00
|
|
|
// Default to repeating the texture as in GRIM
|
|
|
|
resource = (void *)g_resourceloader->loadMaterial(buf, cmap, false);
|
2005-08-13 13:35:43 +00:00
|
|
|
} else {
|
2009-05-31 07:33:18 +00:00
|
|
|
warning("Resource type not understood");
|
2005-08-13 13:35:43 +00:00
|
|
|
}
|
2008-07-30 07:04:32 +00:00
|
|
|
if (!resource)
|
2009-05-31 07:35:15 +00:00
|
|
|
warning("Requested resouce (%s) not found", buf);
|
2005-08-13 13:35:43 +00:00
|
|
|
}
|
2005-08-28 23:25:14 +00:00
|
|
|
|
2013-11-25 23:54:20 +01:00
|
|
|
void GrimEngine::drawTextObjects() {
|
|
|
|
foreach (TextObject *t, TextObject::getPool()) {
|
|
|
|
t->draw();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-17 18:17:07 +02:00
|
|
|
void GrimEngine::playIrisAnimation(Iris::Direction dir, int x, int y, int time) {
|
|
|
|
_iris->play(dir, x, y, time);
|
|
|
|
}
|
|
|
|
|
2009-05-17 08:12:05 +00:00
|
|
|
void GrimEngine::luaUpdate() {
|
2012-01-21 20:18:35 -08:00
|
|
|
if (_savegameLoadRequest || _savegameSaveRequest || _changeHardwareState)
|
2011-04-21 11:05:28 +02:00
|
|
|
return;
|
|
|
|
|
2005-08-13 13:35:43 +00:00
|
|
|
// Update timing information
|
2009-05-07 19:06:31 +00:00
|
|
|
unsigned newStart = g_system->getMillis();
|
2006-01-21 17:22:39 +00:00
|
|
|
if (newStart < _frameStart) {
|
|
|
|
_frameStart = newStart;
|
|
|
|
return;
|
|
|
|
}
|
2005-08-13 13:35:43 +00:00
|
|
|
_frameTime = newStart - _frameStart;
|
|
|
|
_frameStart = newStart;
|
|
|
|
|
2011-10-04 22:01:24 +02:00
|
|
|
if (_mode == PauseMode || _shortFrame) {
|
2011-07-17 19:26:41 +02:00
|
|
|
_frameTime = 0;
|
|
|
|
}
|
|
|
|
|
2011-10-13 20:25:50 +02:00
|
|
|
LuaBase::instance()->update(_frameTime, _movieTime);
|
2011-04-24 16:45:10 +02:00
|
|
|
|
2011-10-04 22:01:24 +02:00
|
|
|
if (_currSet && (_mode == NormalMode || _mode == SmushMode)) {
|
2012-03-07 17:54:54 +01:00
|
|
|
// call updateTalk() before calling update(), since it may modify costumes state, and
|
|
|
|
// the costumes are updated in update().
|
|
|
|
for (Common::List<Actor *>::iterator i = _talkingActors.begin(); i != _talkingActors.end(); ++i) {
|
|
|
|
Actor *a = *i;
|
2012-04-07 20:41:09 +03:00
|
|
|
if (!a->updateTalk(_frameTime)) {
|
2012-03-07 17:54:54 +01:00
|
|
|
i = _talkingActors.reverse_erase(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-24 16:55:36 +02:00
|
|
|
// Update the actors. Do it here so that we are sure to react asap to any change
|
|
|
|
// in the actors state caused by lua.
|
2012-02-24 17:11:55 +01:00
|
|
|
buildActiveActorsList();
|
|
|
|
foreach (Actor *a, _activeActors) {
|
2011-04-24 16:55:36 +02:00
|
|
|
// Note that the actor need not be visible to update chores, for example:
|
|
|
|
// when Manny has just brought Meche back he is offscreen several times
|
|
|
|
// when he needs to perform certain chores
|
2012-02-24 17:11:55 +01:00
|
|
|
a->update(_frameTime);
|
2011-04-24 16:55:36 +02:00
|
|
|
}
|
2011-07-23 15:49:57 +02:00
|
|
|
|
|
|
|
_iris->update(_frameTime);
|
2011-09-07 23:08:59 +02:00
|
|
|
|
2012-03-06 18:31:59 +01:00
|
|
|
foreach (TextObject *t, TextObject::getPool()) {
|
|
|
|
t->update();
|
|
|
|
}
|
2011-05-22 19:46:59 +02:00
|
|
|
}
|
2005-08-13 13:35:43 +00:00
|
|
|
}
|
|
|
|
|
2009-05-17 08:12:05 +00:00
|
|
|
void GrimEngine::updateDisplayScene() {
|
2005-08-28 23:25:14 +00:00
|
|
|
_doFlip = true;
|
2005-08-13 13:35:43 +00:00
|
|
|
|
2011-10-04 22:01:24 +02:00
|
|
|
if (_mode == SmushMode) {
|
2011-05-14 12:11:53 +02:00
|
|
|
if (g_movie->isPlaying()) {
|
|
|
|
_movieTime = g_movie->getMovieTime();
|
|
|
|
if (g_movie->isUpdateNeeded()) {
|
2011-10-01 02:51:55 +02:00
|
|
|
g_driver->prepareMovieFrame(g_movie->getDstSurface());
|
2011-05-14 12:11:53 +02:00
|
|
|
g_movie->clearUpdateNeeded();
|
2005-08-13 13:35:43 +00:00
|
|
|
}
|
2011-05-14 12:11:53 +02:00
|
|
|
int frame = g_movie->getFrame();
|
2011-10-05 19:06:18 +02:00
|
|
|
if (frame >= 0) {
|
2005-08-13 13:35:43 +00:00
|
|
|
if (frame != _prevSmushFrame) {
|
2011-05-14 12:11:53 +02:00
|
|
|
_prevSmushFrame = g_movie->getFrame();
|
2011-08-14 18:35:49 +02:00
|
|
|
g_driver->drawMovieFrame(g_movie->getX(), g_movie->getY());
|
2009-05-25 19:21:58 +00:00
|
|
|
if (_showFps)
|
2005-08-28 23:25:14 +00:00
|
|
|
g_driver->drawEmergString(550, 25, _fps, Color(255, 255, 255));
|
2005-08-13 13:35:43 +00:00
|
|
|
} else
|
2005-08-28 23:25:14 +00:00
|
|
|
_doFlip = false;
|
2008-08-12 14:55:16 +00:00
|
|
|
} else
|
2011-08-14 18:35:49 +02:00
|
|
|
g_driver->releaseMovieFrame();
|
2005-08-13 13:35:43 +00:00
|
|
|
}
|
2011-07-26 00:10:27 +02:00
|
|
|
// Draw Primitives
|
2014-08-03 11:58:12 -07:00
|
|
|
_iris->draw();
|
2020-05-17 13:48:22 +02:00
|
|
|
|
|
|
|
g_movie->drawMovieSubtitle();
|
|
|
|
|
2012-02-18 22:20:16 +01:00
|
|
|
} else if (_mode == NormalMode || _mode == OverworldMode) {
|
2013-12-02 22:26:26 +01:00
|
|
|
updateNormalMode();
|
|
|
|
} else if (_mode == DrawMode) {
|
|
|
|
updateDrawMode();
|
|
|
|
}
|
|
|
|
}
|
2005-08-13 16:25:51 +00:00
|
|
|
|
2013-12-02 22:26:26 +01:00
|
|
|
void GrimEngine::updateNormalMode() {
|
GRIM: Do not draw when flipping is forbidden.
Fixes
"Allocator out of memory: couldn't allocate more memory from linear allocator."
error with TinyGL in GRIM in several places:
- at the beginning of Year 2, after Meche boards the boat (does not happen
when skipping cutscene)
- when loading set bi
And likely in other places.
The issue is that TinyGL queues draw calls in a fixed-size structure
(linear allocator used to quickly queue vertices), and it emits this error
when running out of space. This queue is not flushed for as long as
_flipEnable is false, and this value is controlled by game scripts.
The longer flipping is forbidden, and the more complex the scene is (more
vertices, like in bi), the more likely it is to run out of space and cause
residualvm to error out.
In set bi, missing one flip is enough to exceed buffer space.
In set lm (the one after meche boarding the boat), it takes 5 missed flips
to exceed buffer space (simpler scene), but it still happens in a split
second.
My initial thought was to empty the queue without drawing, but there is no
way to do this with OpenGL and I prefer to avoid TinyGL-only shortcuts.
It seems likely OpenGL to have larger draw operation buffers (maybe
dynamically extended ?), and/or to forcibly stall caller and execute draw
operations when running out of space. In any case, this would add
complexity to residualvm and use more CPU and GPU time for no purpose.
So instead just skip drawing until flipping is allowed again.
2017-04-25 13:05:02 +00:00
|
|
|
if (!_currSet || !_flipEnable)
|
2013-12-02 22:26:26 +01:00
|
|
|
return;
|
2005-08-13 16:25:51 +00:00
|
|
|
|
2013-12-02 22:26:26 +01:00
|
|
|
g_driver->clearScreen();
|
2013-07-12 15:43:16 -07:00
|
|
|
|
2013-12-02 22:26:26 +01:00
|
|
|
drawNormalMode();
|
|
|
|
|
2014-08-03 11:58:12 -07:00
|
|
|
_iris->draw();
|
|
|
|
drawTextObjects();
|
2013-12-02 22:26:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void GrimEngine::updateDrawMode() {
|
|
|
|
_doFlip = false;
|
|
|
|
_prevSmushFrame = 0;
|
|
|
|
_movieTime = 0;
|
2013-07-12 15:43:16 -07:00
|
|
|
}
|
2005-08-13 16:25:51 +00:00
|
|
|
|
2013-07-12 15:43:16 -07:00
|
|
|
void GrimEngine::drawNormalMode() {
|
|
|
|
_prevSmushFrame = 0;
|
|
|
|
_movieTime = 0;
|
2005-08-13 16:25:51 +00:00
|
|
|
|
2013-07-12 15:43:16 -07:00
|
|
|
_currSet->drawBackground();
|
|
|
|
|
|
|
|
// Draw underlying scene components
|
|
|
|
// Background objects are drawn underneath everything except the background
|
|
|
|
// There are a bunch of these, especially in the tube-switcher room
|
|
|
|
_currSet->drawBitmaps(ObjectState::OBJSTATE_BACKGROUND);
|
|
|
|
|
|
|
|
// State objects are drawn on top of other things, such as the flag
|
|
|
|
// on Manny's message tube
|
|
|
|
_currSet->drawBitmaps(ObjectState::OBJSTATE_STATE);
|
|
|
|
|
|
|
|
// Play SMUSH Animations
|
|
|
|
// This should occur on top of all underlying scene objects,
|
|
|
|
// a good example is the tube switcher room where some state objects
|
|
|
|
// need to render underneath the animation or you can't see what's going on
|
|
|
|
// This should not occur on top of everything though or Manny gets covered
|
|
|
|
// up when he's next to Glottis's service room
|
|
|
|
if (g_movie->isPlaying() && _movieSetup == _currSet->getCurrSetup()->_name) {
|
|
|
|
_movieTime = g_movie->getMovieTime();
|
|
|
|
if (g_movie->isUpdateNeeded()) {
|
|
|
|
g_driver->prepareMovieFrame(g_movie->getDstSurface());
|
|
|
|
g_movie->clearUpdateNeeded();
|
2011-07-26 00:10:27 +02:00
|
|
|
}
|
2013-07-12 15:43:16 -07:00
|
|
|
if (g_movie->getFrame() >= 0)
|
|
|
|
g_driver->drawMovieFrame(g_movie->getX(), g_movie->getY());
|
|
|
|
else
|
|
|
|
g_driver->releaseMovieFrame();
|
|
|
|
}
|
2011-07-26 00:10:27 +02:00
|
|
|
|
2013-07-12 15:43:16 -07:00
|
|
|
// Underlay objects must be drawn on top of movies
|
|
|
|
// Otherwise the lighthouse door will always be open as the underlay for
|
|
|
|
// the closed door will be overdrawn by a movie used as background image.
|
|
|
|
_currSet->drawBitmaps(ObjectState::OBJSTATE_UNDERLAY);
|
2005-08-13 16:25:51 +00:00
|
|
|
|
2013-07-12 15:43:16 -07:00
|
|
|
// Draw Primitives
|
|
|
|
foreach (PrimitiveObject *p, PrimitiveObject::getPool()) {
|
|
|
|
p->draw();
|
|
|
|
}
|
2005-08-13 16:25:51 +00:00
|
|
|
|
2013-07-12 15:43:16 -07:00
|
|
|
_currSet->setupCamera();
|
2012-02-13 18:01:03 +01:00
|
|
|
|
2013-07-12 15:43:16 -07:00
|
|
|
g_driver->set3DMode();
|
2012-03-04 18:16:37 +01:00
|
|
|
|
2013-07-12 15:43:16 -07:00
|
|
|
if (_setupChanged) {
|
|
|
|
cameraPostChangeHandle(_currSet->getSetup());
|
|
|
|
_setupChanged = false;
|
2015-03-05 19:12:41 +01:00
|
|
|
setSideTextures(_currSet->getCurrSetup()->_name.c_str());
|
2013-07-12 15:43:16 -07:00
|
|
|
}
|
2012-11-21 22:32:46 +01:00
|
|
|
|
2013-07-12 15:43:16 -07:00
|
|
|
// Draw actors
|
|
|
|
buildActiveActorsList();
|
|
|
|
foreach (Actor *a, _activeActors) {
|
|
|
|
if (a->isVisible())
|
|
|
|
a->draw();
|
|
|
|
}
|
2005-08-13 16:25:51 +00:00
|
|
|
|
2013-07-12 15:43:16 -07:00
|
|
|
flagRefreshShadowMask(false);
|
2005-08-13 20:14:46 +00:00
|
|
|
|
2013-07-12 15:43:16 -07:00
|
|
|
// Draw overlying scene components
|
|
|
|
// The overlay objects should be drawn on top of everything else,
|
|
|
|
// including 3D objects such as Manny and the message tube
|
|
|
|
_currSet->drawBitmaps(ObjectState::OBJSTATE_OVERLAY);
|
2005-08-28 23:25:14 +00:00
|
|
|
}
|
2005-08-13 13:35:43 +00:00
|
|
|
|
2009-05-17 08:12:05 +00:00
|
|
|
void GrimEngine::doFlip() {
|
2011-12-17 12:02:43 +01:00
|
|
|
_frameCounter++;
|
|
|
|
if (!_doFlip) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-08-02 21:41:44 +02:00
|
|
|
if (_showFps && _mode != DrawMode)
|
2005-08-28 23:25:14 +00:00
|
|
|
g_driver->drawEmergString(550, 25, _fps, Color(255, 255, 255));
|
2005-08-13 13:35:43 +00:00
|
|
|
|
2011-12-17 12:02:43 +01:00
|
|
|
if (_flipEnable)
|
2005-08-13 13:35:43 +00:00
|
|
|
g_driver->flipBuffer();
|
|
|
|
|
2011-12-17 12:02:43 +01:00
|
|
|
if (_showFps && _mode != DrawMode) {
|
2011-06-09 18:36:57 -07:00
|
|
|
unsigned int currentTime = g_system->getMillis();
|
|
|
|
unsigned int delta = currentTime - _lastFrameTime;
|
|
|
|
if (delta > 500) {
|
2016-07-18 17:33:27 +02:00
|
|
|
snprintf(_fps, sizeof(_fps), "%7.2f", (double)(_frameCounter * 1000) / (double)delta);
|
2005-08-13 13:35:43 +00:00
|
|
|
_frameCounter = 0;
|
2011-06-09 18:36:57 -07:00
|
|
|
_lastFrameTime = currentTime;
|
2005-08-13 13:35:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-17 08:12:05 +00:00
|
|
|
void GrimEngine::mainLoop() {
|
2004-12-09 23:55:43 +00:00
|
|
|
_movieTime = 0;
|
|
|
|
_frameTime = 0;
|
2009-05-07 19:06:31 +00:00
|
|
|
_frameStart = g_system->getMillis();
|
2005-08-13 13:35:43 +00:00
|
|
|
_frameCounter = 0;
|
2011-06-09 18:36:57 -07:00
|
|
|
_lastFrameTime = 0;
|
2005-08-13 13:35:43 +00:00
|
|
|
_prevSmushFrame = 0;
|
2008-07-05 08:48:39 +00:00
|
|
|
_refreshShadowMask = false;
|
2011-07-17 21:54:42 +02:00
|
|
|
_shortFrame = false;
|
|
|
|
bool resetShortFrame = false;
|
2012-01-21 20:18:35 -08:00
|
|
|
_changeHardwareState = false;
|
2012-01-29 10:28:20 +01:00
|
|
|
_changeFullscreenState = false;
|
2012-02-13 18:01:03 +01:00
|
|
|
_setupChanged = true;
|
2004-11-01 09:47:19 +00:00
|
|
|
|
2004-02-24 21:09:53 +00:00
|
|
|
for (;;) {
|
2009-05-07 19:06:31 +00:00
|
|
|
uint32 startTime = g_system->getMillis();
|
2011-07-17 21:54:42 +02:00
|
|
|
if (_shortFrame) {
|
|
|
|
if (resetShortFrame) {
|
|
|
|
_shortFrame = false;
|
|
|
|
}
|
|
|
|
resetShortFrame = !resetShortFrame;
|
|
|
|
}
|
2008-08-16 17:54:14 +00:00
|
|
|
|
2012-01-31 21:39:34 +01:00
|
|
|
if (shouldQuit())
|
|
|
|
return;
|
|
|
|
|
2005-08-13 13:35:43 +00:00
|
|
|
if (_savegameLoadRequest) {
|
|
|
|
savegameRestore();
|
|
|
|
}
|
|
|
|
if (_savegameSaveRequest) {
|
|
|
|
savegameSave();
|
|
|
|
}
|
|
|
|
|
2017-08-26 22:24:18 +02:00
|
|
|
// If the backend can keep the OpenGL context when switching to fullscreen,
|
|
|
|
// just toggle the fullscreen feature (SDL2 path).
|
|
|
|
if (_changeFullscreenState &&
|
|
|
|
_system->hasFeature(OSystem::kFeatureFullscreenToggleKeepsContext)) {
|
|
|
|
bool fullscreen = _system->getFeatureState(OSystem::kFeatureFullscreenMode);
|
|
|
|
_system->setFeatureState(OSystem::kFeatureFullscreenMode, !fullscreen);
|
|
|
|
_changeFullscreenState = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the backend destroys the OpenGL context or the user switched to a different
|
|
|
|
// renderer, the GFX driver needs to be recreated (SDL1 path).
|
2012-01-29 10:28:20 +01:00
|
|
|
if (_changeHardwareState || _changeFullscreenState) {
|
2012-01-21 20:18:35 -08:00
|
|
|
_changeHardwareState = false;
|
2013-02-04 12:46:42 +01:00
|
|
|
|
2017-08-26 22:24:18 +02:00
|
|
|
bool fullscreen = _system->getFeatureState(OSystem::kFeatureFullscreenMode);
|
2012-01-29 10:28:20 +01:00
|
|
|
if (_changeFullscreenState) {
|
|
|
|
fullscreen = !fullscreen;
|
|
|
|
}
|
2012-01-21 20:18:35 -08:00
|
|
|
|
2012-01-29 10:44:11 +01:00
|
|
|
uint screenWidth = g_driver->getScreenWidth();
|
|
|
|
uint screenHeight = g_driver->getScreenHeight();
|
2012-01-31 11:15:19 +01:00
|
|
|
|
2012-01-21 20:18:35 -08:00
|
|
|
EngineMode mode = getMode();
|
|
|
|
|
2012-01-26 16:17:42 -08:00
|
|
|
_savegameFileName = "";
|
2012-01-21 20:18:35 -08:00
|
|
|
savegameSave();
|
|
|
|
clearPools();
|
|
|
|
|
|
|
|
delete g_driver;
|
2017-08-26 22:24:18 +02:00
|
|
|
g_driver = createRenderer(screenWidth, screenHeight, fullscreen);
|
2012-01-21 20:18:35 -08:00
|
|
|
savegameRestore();
|
|
|
|
|
|
|
|
if (mode == DrawMode) {
|
|
|
|
setMode(GrimEngine::NormalMode);
|
|
|
|
updateDisplayScene();
|
|
|
|
g_driver->storeDisplay();
|
|
|
|
g_driver->dimScreen();
|
|
|
|
}
|
|
|
|
setMode(mode);
|
2012-01-29 10:28:20 +01:00
|
|
|
_changeFullscreenState = false;
|
2012-01-21 20:18:35 -08:00
|
|
|
}
|
|
|
|
|
2014-07-20 00:23:21 +03:00
|
|
|
g_sound->flushTracks();
|
2014-07-18 14:37:29 +03:00
|
|
|
if (g_imuse) {
|
|
|
|
g_imuse->refreshScripts();
|
|
|
|
}
|
2005-08-13 13:35:43 +00:00
|
|
|
|
2004-02-24 21:09:53 +00:00
|
|
|
// Process events
|
2008-08-17 12:01:26 +00:00
|
|
|
Common::Event event;
|
2009-05-07 19:06:31 +00:00
|
|
|
while (g_system->getEventManager()->pollEvent(event)) {
|
2009-05-31 16:09:21 +00:00
|
|
|
// Handle any buttons, keys and joystick operations
|
2011-10-13 20:25:50 +02:00
|
|
|
Common::EventType type = event.type;
|
|
|
|
if (type == Common::EVENT_KEYDOWN || type == Common::EVENT_KEYUP) {
|
2012-02-22 19:13:15 +01:00
|
|
|
if (type == Common::EVENT_KEYDOWN) {
|
2014-03-30 21:43:56 -04:00
|
|
|
// Ignore everything but ESC when movies are playing
|
|
|
|
// This matches the retail and demo versions of EMI
|
|
|
|
// This also allows the PS2 version to skip movies
|
|
|
|
if (_mode == SmushMode && g_grim->getGameType() == GType_MONKEY4) {
|
2013-11-29 22:38:40 +01:00
|
|
|
if (event.kbd.keycode == Common::KEYCODE_ESCAPE) {
|
|
|
|
g_movie->stop();
|
|
|
|
break;
|
|
|
|
}
|
2014-03-30 21:43:56 -04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_mode != DrawMode && _mode != SmushMode && (event.kbd.ascii == 'q')) {
|
2012-02-22 19:13:15 +01:00
|
|
|
handleExit();
|
|
|
|
break;
|
2012-03-06 18:31:59 +01:00
|
|
|
} else if (_mode != DrawMode && (event.kbd.keycode == Common::KEYCODE_PAUSE)) {
|
|
|
|
handlePause();
|
|
|
|
break;
|
2012-02-22 19:13:15 +01:00
|
|
|
} else {
|
2012-03-09 12:09:37 +01:00
|
|
|
handleChars(type, event.kbd);
|
2012-02-22 19:13:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-09 12:09:37 +01:00
|
|
|
handleControls(type, event.kbd);
|
2012-02-22 19:13:15 +01:00
|
|
|
|
2015-01-01 20:47:31 +01:00
|
|
|
if (getGameType() != GType_MONKEY4) {
|
|
|
|
// Allow lua to react to the event.
|
|
|
|
// Without this lua_update switching the entries in the menu is slow because
|
|
|
|
// if the button is not kept pressed the KEYUP will arrive just after the KEYDOWN
|
|
|
|
// and it will break the lua scripts that checks for the state of the button
|
|
|
|
// with GetControlState()
|
|
|
|
//
|
|
|
|
// This call seems to be only necessary to handle Grim's menu correctly.
|
|
|
|
// In EMI it would have the side-effect that luaUpdate() is sometimes called
|
|
|
|
// in the same millisecond which causes getPerSecond() to return 0 for
|
|
|
|
// any given rate which is not compatible with e.g. actor walking.
|
|
|
|
|
|
|
|
// We do not want the scripts to update while a movie is playing in the PS2-version.
|
|
|
|
if (!(getGamePlatform() == Common::kPlatformPS2 && _mode == SmushMode)) {
|
|
|
|
luaUpdate();
|
|
|
|
}
|
2013-11-29 22:40:03 +01:00
|
|
|
}
|
2009-05-31 16:09:21 +00:00
|
|
|
}
|
2014-12-31 13:01:21 +01:00
|
|
|
if (type == Common::EVENT_JOYAXIS_MOTION)
|
|
|
|
handleJoyAxis(event.joystick.axis, event.joystick.position);
|
|
|
|
if (type == Common::EVENT_JOYBUTTON_DOWN || type == Common::EVENT_JOYBUTTON_UP)
|
|
|
|
handleJoyButton(type, event.joystick.button);
|
2018-07-27 19:19:11 +02:00
|
|
|
if (type == Common::EVENT_SCREEN_CHANGED) {
|
|
|
|
handleUserPaint();
|
|
|
|
}
|
2004-02-24 21:09:53 +00:00
|
|
|
}
|
|
|
|
|
2013-05-07 18:57:03 -07:00
|
|
|
if (_mode != PauseMode) {
|
|
|
|
// Draw the display scene before doing the luaUpdate.
|
|
|
|
// This give a large performance boost as OpenGL stores commands
|
|
|
|
// in a queue on the gpu to be rendered later. When doFlip is
|
|
|
|
// called the cpu must wait for the gpu to finish its queue.
|
|
|
|
// Now, it will queue all the OpenGL commands and draw them on the
|
|
|
|
// GPU while the CPU is busy updating the game world.
|
|
|
|
updateDisplayScene();
|
|
|
|
}
|
|
|
|
|
2014-07-27 19:54:51 +02:00
|
|
|
if (_mode != PauseMode) {
|
|
|
|
doFlip();
|
|
|
|
}
|
|
|
|
|
2013-11-29 22:40:03 +01:00
|
|
|
// We do not want the scripts to update while a movie is playing in the PS2-version.
|
|
|
|
if (!(getGamePlatform() == Common::kPlatformPS2 && _mode == SmushMode)) {
|
|
|
|
luaUpdate();
|
|
|
|
}
|
2004-11-01 16:36:41 +00:00
|
|
|
|
2005-01-03 16:27:57 +00:00
|
|
|
if (g_imuseState != -1) {
|
2012-01-22 14:14:15 +01:00
|
|
|
g_sound->setMusicState(g_imuseState);
|
2005-01-03 16:27:57 +00:00
|
|
|
g_imuseState = -1;
|
|
|
|
}
|
2008-08-16 17:54:14 +00:00
|
|
|
|
2009-05-07 19:06:31 +00:00
|
|
|
uint32 endTime = g_system->getMillis();
|
2008-08-16 17:54:14 +00:00
|
|
|
if (startTime > endTime)
|
|
|
|
continue;
|
|
|
|
uint32 diffTime = endTime - startTime;
|
2008-08-17 05:36:41 +00:00
|
|
|
if (_speedLimitMs == 0)
|
|
|
|
continue;
|
2008-08-16 17:54:14 +00:00
|
|
|
if (diffTime < _speedLimitMs) {
|
|
|
|
uint32 delayTime = _speedLimitMs - diffTime;
|
2009-05-07 19:06:31 +00:00
|
|
|
g_system->delayMillis(delayTime);
|
2008-08-16 17:54:14 +00:00
|
|
|
}
|
2004-02-24 21:09:53 +00:00
|
|
|
}
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
2012-01-21 20:18:35 -08:00
|
|
|
void GrimEngine::changeHardwareState() {
|
|
|
|
_changeHardwareState = true;
|
|
|
|
}
|
|
|
|
|
2011-05-28 11:31:12 +02:00
|
|
|
void GrimEngine::saveGame(const Common::String &file) {
|
|
|
|
_savegameFileName = file;
|
|
|
|
_savegameSaveRequest = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GrimEngine::loadGame(const Common::String &file) {
|
|
|
|
_savegameFileName = file;
|
|
|
|
_savegameLoadRequest = true;
|
|
|
|
}
|
|
|
|
|
2009-05-17 08:12:05 +00:00
|
|
|
void GrimEngine::savegameRestore() {
|
2011-10-07 23:05:20 +02:00
|
|
|
debug("GrimEngine::savegameRestore() started.");
|
2004-11-01 16:36:41 +00:00
|
|
|
_savegameLoadRequest = false;
|
2011-05-22 16:40:56 -07:00
|
|
|
Common::String filename;
|
2011-05-17 20:48:58 -07:00
|
|
|
if (_savegameFileName.size() == 0) {
|
2011-05-22 16:40:56 -07:00
|
|
|
filename = "grim.sav";
|
2004-11-01 16:36:41 +00:00
|
|
|
} else {
|
2011-05-22 16:40:56 -07:00
|
|
|
filename = _savegameFileName;
|
2004-11-01 16:36:41 +00:00
|
|
|
}
|
2011-07-18 14:35:16 +02:00
|
|
|
_savedState = SaveGame::openForLoading(filename);
|
2012-03-09 15:44:53 +01:00
|
|
|
if (!_savedState || !_savedState->isCompatible())
|
2008-08-02 21:03:23 +00:00
|
|
|
return;
|
2014-07-18 14:37:29 +03:00
|
|
|
if (g_imuse) {
|
|
|
|
g_imuse->stopAllSounds();
|
|
|
|
g_imuse->resetState();
|
|
|
|
}
|
2011-05-14 12:11:53 +02:00
|
|
|
g_movie->stop();
|
2014-07-18 14:37:29 +03:00
|
|
|
if (g_imuse)
|
|
|
|
g_imuse->pause(true);
|
2011-05-14 12:11:53 +02:00
|
|
|
g_movie->pause(true);
|
2013-11-24 13:55:41 +01:00
|
|
|
if (g_registry)
|
|
|
|
g_registry->save();
|
2005-01-14 10:53:29 +00:00
|
|
|
|
2014-05-29 15:35:46 -07:00
|
|
|
_selectedActor = nullptr;
|
2011-09-19 16:53:08 +02:00
|
|
|
delete _currSet;
|
2014-05-29 15:35:46 -07:00
|
|
|
_currSet = nullptr;
|
2011-03-21 05:16:27 +08:00
|
|
|
|
2011-11-21 22:07:12 +01:00
|
|
|
Bitmap::getPool().restoreObjects(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Bitmaps restored successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-11-21 22:07:12 +01:00
|
|
|
Font::getPool().restoreObjects(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Fonts restored successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-11-21 22:07:12 +01:00
|
|
|
ObjectState::getPool().restoreObjects(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "ObjectStates restored successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-11-21 22:07:12 +01:00
|
|
|
Set::getPool().restoreObjects(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Sets restored successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-11-21 22:07:12 +01:00
|
|
|
TextObject::getPool().restoreObjects(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "TextObjects restored successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-11-21 22:07:12 +01:00
|
|
|
PrimitiveObject::getPool().restoreObjects(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "PrimitiveObjects restored successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-11-21 22:07:12 +01:00
|
|
|
Actor::getPool().restoreObjects(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Actors restored successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2012-11-12 23:07:32 +01:00
|
|
|
if (getGameType() == GType_MONKEY4) {
|
|
|
|
PoolSound::getPool().restoreObjects(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Pool sounds saved successfully.");
|
2013-12-04 00:55:14 +01:00
|
|
|
|
|
|
|
Layer::getPool().restoreObjects(_savedState);
|
|
|
|
Debug::debug(Debug::Engine, "Layers restored successfully.");
|
2012-11-12 23:07:32 +01:00
|
|
|
}
|
|
|
|
|
2011-05-26 10:24:09 -07:00
|
|
|
restoreGRIM();
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Engine restored successfully.");
|
2011-03-21 05:16:27 +08:00
|
|
|
|
2011-04-24 15:41:40 +02:00
|
|
|
g_driver->restoreState(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Renderer restored successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2013-07-14 20:47:46 +02:00
|
|
|
g_sound->restoreState(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "iMuse restored successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-05-14 12:11:53 +02:00
|
|
|
g_movie->restoreState(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Movie restored successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-07-17 21:21:06 +02:00
|
|
|
_iris->restoreState(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Iris restored successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-05-28 14:46:36 +02:00
|
|
|
lua_Restore(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Lua restored successfully.");
|
2011-05-28 14:46:36 +02:00
|
|
|
|
2005-12-26 02:36:00 +00:00
|
|
|
delete _savedState;
|
2011-04-29 18:57:00 +02:00
|
|
|
|
2012-02-12 21:39:19 +01:00
|
|
|
//Re-read the values, since we may have been in some state that changed them when loading the savegame,
|
|
|
|
//e.g. running a cutscene, which sets the sfx volume to 0.
|
|
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
|
|
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
|
|
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
|
|
|
|
|
2011-10-13 20:25:50 +02:00
|
|
|
LuaBase::instance()->postRestoreHandle();
|
2014-07-18 14:37:29 +03:00
|
|
|
if (g_imuse)
|
|
|
|
g_imuse->pause(false);
|
2011-05-14 12:11:53 +02:00
|
|
|
g_movie->pause(false);
|
2011-10-07 23:05:20 +02:00
|
|
|
debug("GrimEngine::savegameRestore() finished.");
|
2011-07-17 21:54:42 +02:00
|
|
|
|
|
|
|
_shortFrame = true;
|
2011-07-18 15:05:33 +02:00
|
|
|
clearEventQueue();
|
2012-02-24 17:11:55 +01:00
|
|
|
invalidateActiveActorsList();
|
2012-03-09 11:15:10 +01:00
|
|
|
buildActiveActorsList();
|
2013-01-11 12:39:12 +01:00
|
|
|
|
|
|
|
_currSet->setupCamera();
|
|
|
|
g_driver->set3DMode();
|
2004-11-01 16:36:41 +00:00
|
|
|
}
|
|
|
|
|
2011-05-26 10:24:09 -07:00
|
|
|
void GrimEngine::restoreGRIM() {
|
|
|
|
_savedState->beginSection('GRIM');
|
2011-05-24 22:18:01 -07:00
|
|
|
|
2011-10-04 22:01:24 +02:00
|
|
|
_mode = (EngineMode)_savedState->readLEUint32();
|
|
|
|
_previousMode = (EngineMode)_savedState->readLEUint32();
|
2011-10-02 19:15:29 +02:00
|
|
|
|
2011-05-26 10:24:09 -07:00
|
|
|
// Actor stuff
|
2012-01-27 15:09:13 -08:00
|
|
|
int32 id = _savedState->readLESint32();
|
2011-03-21 05:16:27 +08:00
|
|
|
if (id != 0) {
|
2011-11-21 22:07:12 +01:00
|
|
|
_selectedActor = Actor::getPool().getObject(id);
|
2011-03-21 05:16:27 +08:00
|
|
|
}
|
2011-05-26 10:24:09 -07:00
|
|
|
|
|
|
|
//TextObject stuff
|
2012-01-27 11:47:28 -08:00
|
|
|
_sayLineDefaults.setFGColor(_savedState->readColor());
|
2012-01-27 15:09:13 -08:00
|
|
|
_sayLineDefaults.setFont(Font::getPool().getObject(_savedState->readLESint32()));
|
2011-05-26 10:24:09 -07:00
|
|
|
_sayLineDefaults.setHeight(_savedState->readLESint32());
|
|
|
|
_sayLineDefaults.setJustify(_savedState->readLESint32());
|
|
|
|
_sayLineDefaults.setWidth(_savedState->readLESint32());
|
|
|
|
_sayLineDefaults.setX(_savedState->readLESint32());
|
|
|
|
_sayLineDefaults.setY(_savedState->readLESint32());
|
|
|
|
_sayLineDefaults.setDuration(_savedState->readLESint32());
|
2013-01-16 14:49:37 +01:00
|
|
|
if (_savedState->saveMinorVersion() > 5) {
|
|
|
|
_movieSubtitle = TextObject::getPool().getObject(_savedState->readLESint32());
|
|
|
|
}
|
2011-05-26 10:24:09 -07:00
|
|
|
|
2011-09-19 16:53:08 +02:00
|
|
|
// Set stuff
|
2012-01-27 15:09:13 -08:00
|
|
|
_currSet = Set::getPool().getObject(_savedState->readLESint32());
|
2013-01-13 17:09:29 +01:00
|
|
|
if (_savedState->saveMinorVersion() > 4) {
|
|
|
|
_movieSetup = _savedState->readString();
|
|
|
|
} else {
|
|
|
|
_movieSetup = _currSet->getCurrSetup()->_name;
|
|
|
|
}
|
2011-05-01 18:51:26 +02:00
|
|
|
|
2011-05-26 10:24:09 -07:00
|
|
|
_savedState->endSection();
|
2011-05-01 18:51:26 +02:00
|
|
|
}
|
|
|
|
|
2009-10-17 12:48:23 +00:00
|
|
|
void GrimEngine::storeSaveGameImage(SaveGame *state) {
|
2016-07-17 09:21:21 +00:00
|
|
|
const Graphics::PixelFormat image_format = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
|
2006-05-14 07:51:41 +00:00
|
|
|
int width = 250, height = 188;
|
|
|
|
Bitmap *screenshot;
|
|
|
|
|
2011-10-07 23:05:20 +02:00
|
|
|
debug("GrimEngine::StoreSaveGameImage() started.");
|
2006-05-14 07:51:41 +00:00
|
|
|
|
2017-04-26 11:40:00 +00:00
|
|
|
screenshot = g_driver->getScreenshot(width, height, true);
|
2009-10-17 12:48:23 +00:00
|
|
|
state->beginSection('SIMG');
|
2006-05-14 07:51:41 +00:00
|
|
|
if (screenshot) {
|
2011-05-20 21:02:30 +02:00
|
|
|
int size = screenshot->getWidth() * screenshot->getHeight();
|
2011-09-18 18:46:20 +02:00
|
|
|
screenshot->setActiveImage(0);
|
2016-07-17 09:21:21 +00:00
|
|
|
screenshot->getBitmapData()->convertToColorFormat(image_format);
|
2012-01-24 19:02:50 +01:00
|
|
|
uint16 *data = (uint16 *)screenshot->getData().getRawBuffer();
|
2011-05-20 21:02:30 +02:00
|
|
|
for (int l = 0; l < size; l++) {
|
|
|
|
state->writeLEUint16(data[l]);
|
|
|
|
}
|
2006-05-14 07:51:41 +00:00
|
|
|
} else {
|
2009-05-31 07:33:18 +00:00
|
|
|
error("Unable to store screenshot");
|
2006-05-14 07:51:41 +00:00
|
|
|
}
|
2009-10-17 12:48:23 +00:00
|
|
|
state->endSection();
|
2011-05-16 22:32:59 +02:00
|
|
|
delete screenshot;
|
2011-10-07 23:05:20 +02:00
|
|
|
debug("GrimEngine::StoreSaveGameImage() finished.");
|
2006-05-14 07:51:41 +00:00
|
|
|
}
|
|
|
|
|
2009-05-17 08:12:05 +00:00
|
|
|
void GrimEngine::savegameSave() {
|
2011-10-07 23:05:20 +02:00
|
|
|
debug("GrimEngine::savegameSave() started.");
|
2004-11-01 16:36:41 +00:00
|
|
|
_savegameSaveRequest = false;
|
2012-10-04 22:46:18 +02:00
|
|
|
Common::String filename;
|
2011-05-17 20:48:58 -07:00
|
|
|
if (_savegameFileName.size() == 0) {
|
2012-10-04 22:46:18 +02:00
|
|
|
filename = "grim.sav";
|
2004-11-01 16:36:41 +00:00
|
|
|
} else {
|
2012-10-04 22:46:18 +02:00
|
|
|
filename = _savegameFileName;
|
|
|
|
}
|
|
|
|
if (getGameType() == GType_MONKEY4 && filename.contains('/')) {
|
|
|
|
filename = Common::lastPathComponent(filename, '/');
|
2004-11-01 16:36:41 +00:00
|
|
|
}
|
2011-07-18 14:35:16 +02:00
|
|
|
_savedState = SaveGame::openForSaving(filename);
|
2011-07-18 16:33:52 +02:00
|
|
|
if (!_savedState) {
|
|
|
|
//TODO: Translate this!
|
2020-09-03 02:01:03 +02:00
|
|
|
GUI::displayErrorDialog(_("Error: the game could not be saved."));
|
2008-08-02 21:03:23 +00:00
|
|
|
return;
|
2011-07-18 16:33:52 +02:00
|
|
|
}
|
2004-11-01 16:36:41 +00:00
|
|
|
|
2006-05-14 07:51:41 +00:00
|
|
|
storeSaveGameImage(_savedState);
|
|
|
|
|
2014-07-18 14:37:29 +03:00
|
|
|
if (g_imuse)
|
|
|
|
g_imuse->pause(true);
|
2011-05-14 12:11:53 +02:00
|
|
|
g_movie->pause(true);
|
2005-01-14 10:51:20 +00:00
|
|
|
|
2005-01-12 23:28:47 +00:00
|
|
|
savegameCallback();
|
|
|
|
|
2011-11-21 22:07:12 +01:00
|
|
|
Bitmap::getPool().saveObjects(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Bitmaps saved successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-11-21 22:07:12 +01:00
|
|
|
Font::getPool().saveObjects(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Fonts saved successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-11-21 22:07:12 +01:00
|
|
|
ObjectState::getPool().saveObjects(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "ObjectStates saved successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-11-21 22:07:12 +01:00
|
|
|
Set::getPool().saveObjects(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Sets saved successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-11-21 22:07:12 +01:00
|
|
|
TextObject::getPool().saveObjects(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "TextObjects saved successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-11-21 22:07:12 +01:00
|
|
|
PrimitiveObject::getPool().saveObjects(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "PrimitiveObjects saved successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-11-21 22:07:12 +01:00
|
|
|
Actor::getPool().saveObjects(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Actors saved successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2012-11-12 23:07:32 +01:00
|
|
|
if (getGameType() == GType_MONKEY4) {
|
|
|
|
PoolSound::getPool().saveObjects(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Pool sounds saved successfully.");
|
2013-12-04 00:55:14 +01:00
|
|
|
|
|
|
|
Layer::getPool().saveObjects(_savedState);
|
|
|
|
Debug::debug(Debug::Engine, "Layers saved successfully.");
|
2012-11-12 23:07:32 +01:00
|
|
|
}
|
|
|
|
|
2011-05-26 10:24:09 -07:00
|
|
|
saveGRIM();
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Engine saved successfully.");
|
2009-06-22 14:11:40 +00:00
|
|
|
|
2011-04-24 15:41:40 +02:00
|
|
|
g_driver->saveState(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Renderer saved successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2013-07-14 20:47:46 +02:00
|
|
|
g_sound->saveState(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "iMuse saved successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-05-14 12:11:53 +02:00
|
|
|
g_movie->saveState(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Movie saved successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-07-17 21:21:06 +02:00
|
|
|
_iris->saveState(_savedState);
|
2013-03-28 15:30:08 +11:00
|
|
|
Debug::debug(Debug::Engine, "Iris saved successfully.");
|
2011-10-07 23:05:20 +02:00
|
|
|
|
2011-05-28 14:46:36 +02:00
|
|
|
lua_Save(_savedState);
|
2005-12-26 02:36:00 +00:00
|
|
|
|
|
|
|
delete _savedState;
|
2005-01-14 10:51:20 +00:00
|
|
|
|
2014-07-18 14:37:29 +03:00
|
|
|
if (g_imuse)
|
|
|
|
g_imuse->pause(false);
|
2011-05-14 12:11:53 +02:00
|
|
|
g_movie->pause(false);
|
2011-10-07 23:05:20 +02:00
|
|
|
debug("GrimEngine::savegameSave() finished.");
|
2011-07-18 15:05:33 +02:00
|
|
|
|
2011-07-18 15:07:37 +02:00
|
|
|
_shortFrame = true;
|
2011-07-18 15:05:33 +02:00
|
|
|
clearEventQueue();
|
2004-11-01 16:36:41 +00:00
|
|
|
}
|
|
|
|
|
2011-05-26 10:24:09 -07:00
|
|
|
void GrimEngine::saveGRIM() {
|
|
|
|
_savedState->beginSection('GRIM');
|
2009-06-22 14:11:40 +00:00
|
|
|
|
2011-10-04 22:01:24 +02:00
|
|
|
_savedState->writeLEUint32((uint32)_mode);
|
|
|
|
_savedState->writeLEUint32((uint32)_previousMode);
|
2011-10-02 19:15:29 +02:00
|
|
|
|
2011-05-26 10:24:09 -07:00
|
|
|
//Actor stuff
|
2011-03-21 05:16:27 +08:00
|
|
|
if (_selectedActor) {
|
2012-01-27 15:09:13 -08:00
|
|
|
_savedState->writeLESint32(_selectedActor->getId());
|
2011-03-21 05:16:27 +08:00
|
|
|
} else {
|
2012-01-27 15:09:13 -08:00
|
|
|
_savedState->writeLESint32(0);
|
2009-06-22 21:20:12 +00:00
|
|
|
}
|
|
|
|
|
2011-05-26 10:24:09 -07:00
|
|
|
//TextObject stuff
|
2012-01-27 11:47:28 -08:00
|
|
|
_savedState->writeColor(_sayLineDefaults.getFGColor());
|
2012-01-27 15:09:13 -08:00
|
|
|
_savedState->writeLESint32(_sayLineDefaults.getFont()->getId());
|
2011-05-26 10:24:09 -07:00
|
|
|
_savedState->writeLESint32(_sayLineDefaults.getHeight());
|
|
|
|
_savedState->writeLESint32(_sayLineDefaults.getJustify());
|
|
|
|
_savedState->writeLESint32(_sayLineDefaults.getWidth());
|
|
|
|
_savedState->writeLESint32(_sayLineDefaults.getX());
|
|
|
|
_savedState->writeLESint32(_sayLineDefaults.getY());
|
|
|
|
_savedState->writeLESint32(_sayLineDefaults.getDuration());
|
2013-01-16 14:49:37 +01:00
|
|
|
_savedState->writeLESint32(_movieSubtitle ? _movieSubtitle->getId() : 0);
|
2011-05-26 10:24:09 -07:00
|
|
|
|
2011-09-19 16:53:08 +02:00
|
|
|
//Set stuff
|
2012-01-27 15:09:13 -08:00
|
|
|
_savedState->writeLESint32(_currSet->getId());
|
2013-01-13 17:09:29 +01:00
|
|
|
_savedState->writeString(_movieSetup);
|
2011-05-01 18:51:26 +02:00
|
|
|
|
2011-05-26 10:24:09 -07:00
|
|
|
_savedState->endSection();
|
2011-05-01 18:51:26 +02:00
|
|
|
}
|
|
|
|
|
2011-09-19 16:53:08 +02:00
|
|
|
Set *GrimEngine::findSet(const Common::String &name) {
|
2005-07-10 18:57:27 +00:00
|
|
|
// Find scene object
|
2011-11-21 22:07:12 +01:00
|
|
|
foreach (Set *s, Set::getPool()) {
|
|
|
|
if (s->getName() == name)
|
|
|
|
return s;
|
2005-07-10 18:57:27 +00:00
|
|
|
}
|
2014-05-29 15:35:46 -07:00
|
|
|
return nullptr;
|
2005-07-10 18:57:27 +00:00
|
|
|
}
|
|
|
|
|
2011-09-19 16:53:08 +02:00
|
|
|
void GrimEngine::setSetLock(const char *name, bool lockStatus) {
|
|
|
|
Set *scene = findSet(name);
|
2009-05-09 17:47:28 +00:00
|
|
|
|
2008-07-30 07:04:32 +00:00
|
|
|
if (!scene) {
|
2011-10-07 23:05:20 +02:00
|
|
|
Debug::warning(Debug::Engine, "Set object '%s' not found in list", name);
|
2005-07-10 18:57:27 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Change the locking status
|
2005-08-10 08:33:45 +00:00
|
|
|
scene->_locked = lockStatus;
|
2005-07-10 18:57:27 +00:00
|
|
|
}
|
|
|
|
|
2011-09-19 16:53:08 +02:00
|
|
|
Set *GrimEngine::loadSet(const Common::String &name) {
|
|
|
|
Set *s = findSet(name);
|
2011-07-10 12:23:23 +02:00
|
|
|
|
|
|
|
if (!s) {
|
|
|
|
Common::String filename(name);
|
|
|
|
// EMI-scripts refer to their .setb files as .set
|
|
|
|
if (g_grim->getGameType() == GType_MONKEY4) {
|
|
|
|
filename += "b";
|
|
|
|
}
|
2011-12-19 18:50:14 +01:00
|
|
|
Common::SeekableReadStream *stream;
|
|
|
|
stream = g_resourceloader->openNewStreamFile(filename.c_str());
|
2013-07-09 21:12:55 +02:00
|
|
|
if (!stream)
|
2013-06-02 16:14:47 +02:00
|
|
|
error("Could not find scene file %s", name.c_str());
|
2011-12-19 18:50:14 +01:00
|
|
|
|
|
|
|
s = new Set(name, stream);
|
2012-01-20 12:06:01 -08:00
|
|
|
delete stream;
|
2005-07-17 23:40:22 +00:00
|
|
|
}
|
2011-07-10 12:23:23 +02:00
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2011-09-19 16:53:08 +02:00
|
|
|
void GrimEngine::setSet(const char *name) {
|
|
|
|
setSet(loadSet(name));
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
2005-07-10 18:57:27 +00:00
|
|
|
|
2011-09-19 16:53:08 +02:00
|
|
|
void GrimEngine::setSet(Set *scene) {
|
|
|
|
if (scene == _currSet)
|
2011-06-17 17:11:08 -07:00
|
|
|
return;
|
2011-07-26 16:07:38 +02:00
|
|
|
|
2013-12-04 00:11:26 +01:00
|
|
|
if (getGameType() == GType_MONKEY4) {
|
|
|
|
foreach (PoolSound *s, PoolSound::getPool()) {
|
|
|
|
s->stop();
|
|
|
|
}
|
|
|
|
}
|
2012-01-06 13:32:30 +01:00
|
|
|
// Stop the actors. This fixes bug #289 (https://github.com/residualvm/residualvm/issues/289)
|
2011-07-26 16:07:38 +02:00
|
|
|
// and it makes sense too, since when changing set the directions
|
|
|
|
// and coords change too.
|
2011-11-21 22:07:12 +01:00
|
|
|
foreach (Actor *a, Actor::getPool()) {
|
2011-07-26 16:07:38 +02:00
|
|
|
a->stopWalking();
|
|
|
|
}
|
|
|
|
|
2011-09-19 16:53:08 +02:00
|
|
|
Set *lastSet = _currSet;
|
|
|
|
_currSet = scene;
|
|
|
|
_currSet->setSoundParameters(20, 127);
|
2005-07-17 23:40:22 +00:00
|
|
|
// should delete the old scene after setting the new one
|
2011-09-19 16:53:08 +02:00
|
|
|
if (lastSet && !lastSet->_locked) {
|
|
|
|
delete lastSet;
|
2005-07-17 23:40:22 +00:00
|
|
|
}
|
2011-07-17 21:54:42 +02:00
|
|
|
_shortFrame = true;
|
2012-02-13 18:01:03 +01:00
|
|
|
_setupChanged = true;
|
2012-02-24 17:11:55 +01:00
|
|
|
invalidateActiveActorsList();
|
2005-07-10 18:57:27 +00:00
|
|
|
}
|
|
|
|
|
2009-06-08 22:25:14 +00:00
|
|
|
void GrimEngine::makeCurrentSetup(int num) {
|
2011-09-19 16:53:08 +02:00
|
|
|
int prevSetup = g_grim->getCurrSet()->getSetup();
|
2009-06-09 15:34:59 +00:00
|
|
|
if (prevSetup != num) {
|
2011-09-19 16:53:08 +02:00
|
|
|
getCurrSet()->setSetup(num);
|
|
|
|
getCurrSet()->setSoundParameters(20, 127);
|
2009-06-09 15:34:59 +00:00
|
|
|
cameraChangeHandle(prevSetup, num);
|
|
|
|
// here should be set sound position
|
2012-02-13 18:01:03 +01:00
|
|
|
|
|
|
|
_setupChanged = true;
|
2009-06-09 15:34:59 +00:00
|
|
|
}
|
2009-06-08 22:25:14 +00:00
|
|
|
}
|
|
|
|
|
2009-05-17 08:12:05 +00:00
|
|
|
void GrimEngine::setTextSpeed(int speed) {
|
2005-04-08 11:47:47 +00:00
|
|
|
if (speed < 1)
|
|
|
|
_textSpeed = 1;
|
|
|
|
if (speed > 10)
|
|
|
|
_textSpeed = 10;
|
|
|
|
_textSpeed = speed;
|
|
|
|
}
|
2008-08-17 12:01:26 +00:00
|
|
|
|
2009-05-17 08:12:05 +00:00
|
|
|
float GrimEngine::getControlAxis(int num) {
|
2014-12-31 13:01:21 +01:00
|
|
|
int idx = num - KEYCODE_AXIS_JOY1_X;
|
|
|
|
if (idx >= 0 && idx < NUM_JOY_AXES) {
|
|
|
|
return _joyAxisPosition[idx];
|
|
|
|
}
|
2008-08-17 12:01:26 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-05-17 08:12:05 +00:00
|
|
|
bool GrimEngine::getControlState(int num) {
|
2008-08-17 12:01:26 +00:00
|
|
|
return _controlsState[num];
|
|
|
|
}
|
2009-05-25 06:49:57 +00:00
|
|
|
|
2011-05-05 11:25:08 +02:00
|
|
|
float GrimEngine::getPerSecond(float rate) const {
|
2011-04-26 21:55:55 +02:00
|
|
|
return rate * _frameTime / 1000;
|
|
|
|
}
|
|
|
|
|
2012-02-24 17:11:55 +01:00
|
|
|
void GrimEngine::invalidateActiveActorsList() {
|
|
|
|
_buildActiveActorsList = true;
|
|
|
|
}
|
|
|
|
|
2012-08-07 00:21:27 +02:00
|
|
|
void GrimEngine::immediatelyRemoveActor(Actor *actor) {
|
|
|
|
_activeActors.remove(actor);
|
|
|
|
_talkingActors.remove(actor);
|
|
|
|
}
|
|
|
|
|
2012-02-24 17:11:55 +01:00
|
|
|
void GrimEngine::buildActiveActorsList() {
|
|
|
|
if (!_buildActiveActorsList) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
_activeActors.clear();
|
|
|
|
foreach (Actor *a, Actor::getPool()) {
|
GRIM: Drop off-screen buffers
These were present to implement actor freezing in software rendering mode
in the way original engine was intended for performance reason.
In residualvm, software rendering will generalise the principle through
dirty-rectangles management, so off-screen buffers should not be needed.
Also, properly implementing them requires invasive changes (move previous
draw call list from global OpenGL context to individual off-screen buffers,
along with associated linear vertex allocator, adding a new draw call to
track requested buffer changes until final on-screen frame buffer
presentation).
So instead of such added complexity, lie to lua API about actor not being
in set but keep it in so it is part of normal redraw sequence.
Fixes disappearing actors in cn, bi.
Likely also fixes at, ly, sh, mn, dd which uses free/thaw lua API, but
which I did not check.
2017-04-25 00:00:33 +00:00
|
|
|
if (((_mode == NormalMode || _mode == DrawMode) && a->isDrawableInSet(_currSet->getName())) ||
|
2013-12-02 20:59:25 +01:00
|
|
|
a->isInOverworld()) {
|
2013-07-14 10:16:27 -07:00
|
|
|
_activeActors.push_back(a);
|
2012-02-24 17:11:55 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
_buildActiveActorsList = false;
|
|
|
|
}
|
|
|
|
|
2012-03-04 18:16:37 +01:00
|
|
|
void GrimEngine::addTalkingActor(Actor *a) {
|
|
|
|
_talkingActors.push_back(a);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GrimEngine::areActorsTalking() const {
|
2012-04-02 18:47:41 -07:00
|
|
|
//This takes into account that there may be actors which are still talking, but in the background.
|
|
|
|
bool talking = false;
|
|
|
|
foreach (Actor *a, _talkingActors) {
|
2013-01-24 16:13:18 +01:00
|
|
|
if (a->isTalkingForeground()) {
|
2012-04-02 18:47:41 -07:00
|
|
|
talking = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return talking;
|
2012-03-04 18:16:37 +01:00
|
|
|
}
|
|
|
|
|
2012-05-05 18:02:31 -07:00
|
|
|
void GrimEngine::setMovieSubtitle(TextObject *to) {
|
2012-03-21 18:14:58 +01:00
|
|
|
if (_movieSubtitle != to) {
|
|
|
|
delete _movieSubtitle;
|
|
|
|
_movieSubtitle = to;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-17 13:48:22 +02:00
|
|
|
void GrimEngine::drawMovieSubtitle() {
|
|
|
|
if (_movieSubtitle)
|
|
|
|
_movieSubtitle->draw();
|
|
|
|
}
|
|
|
|
|
2013-01-08 00:33:59 +01:00
|
|
|
void GrimEngine::setMovieSetup() {
|
|
|
|
_movieSetup = _currSet->getCurrSetup()->_name;
|
|
|
|
}
|
|
|
|
|
2012-12-19 23:24:49 +01:00
|
|
|
void GrimEngine::setMode(EngineMode mode) {
|
|
|
|
_mode = mode;
|
|
|
|
invalidateActiveActorsList();
|
|
|
|
}
|
|
|
|
|
2011-07-18 15:05:33 +02:00
|
|
|
void GrimEngine::clearEventQueue() {
|
|
|
|
Common::Event event;
|
|
|
|
while (g_system->getEventManager()->pollEvent(event)) {
|
|
|
|
}
|
2011-07-24 16:19:17 +02:00
|
|
|
|
|
|
|
for (int i = 0; i < KEYCODE_EXTRA_LAST; ++i) {
|
|
|
|
_controlsState[i] = false;
|
|
|
|
}
|
2011-07-18 15:05:33 +02:00
|
|
|
}
|
|
|
|
|
2012-01-31 21:39:34 +01:00
|
|
|
bool GrimEngine::hasFeature(EngineFeature f) const {
|
2012-03-26 20:28:31 -07:00
|
|
|
return
|
2020-06-22 08:14:16 +02:00
|
|
|
(f == kSupportsReturnToLauncher) ||
|
2020-10-03 17:13:54 +02:00
|
|
|
(f == kSupportsLoadingDuringRuntime);
|
2012-01-31 21:39:34 +01:00
|
|
|
}
|
|
|
|
|
2013-02-07 17:08:11 +01:00
|
|
|
void GrimEngine::pauseEngineIntern(bool pause) {
|
2014-07-18 14:37:29 +03:00
|
|
|
if (g_imuse)
|
|
|
|
g_imuse->pause(pause);
|
2014-08-09 12:05:07 -07:00
|
|
|
if (g_movie)
|
|
|
|
g_movie->pause(pause);
|
2013-12-01 20:32:44 +01:00
|
|
|
|
|
|
|
if (pause) {
|
|
|
|
_pauseStartTime = _system->getMillis();
|
|
|
|
} else {
|
|
|
|
_frameStart += _system->getMillis() - _pauseStartTime;
|
|
|
|
}
|
2013-02-07 17:08:11 +01:00
|
|
|
}
|
|
|
|
|
2015-03-05 19:12:41 +01:00
|
|
|
|
2015-03-22 13:05:29 +01:00
|
|
|
Graphics::Surface *loadPNG(const Common::String &filename) {
|
2015-03-05 19:12:41 +01:00
|
|
|
Image::PNGDecoder d;
|
|
|
|
Common::SeekableReadStream *s = SearchMan.createReadStreamForMember(filename);
|
|
|
|
if (!s)
|
|
|
|
return nullptr;
|
|
|
|
d.loadStream(*s);
|
|
|
|
delete s;
|
|
|
|
|
|
|
|
Graphics::Surface *srf = d.getSurface()->convertTo(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
|
2015-03-22 13:05:29 +01:00
|
|
|
return srf;
|
2015-03-05 19:12:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void GrimEngine::setSideTextures(const Common::String &setup) {
|
2015-08-14 15:16:40 +02:00
|
|
|
if (! g_system->hasFeature(OSystem::kFeatureSideTextures))
|
|
|
|
return;
|
2015-03-22 13:05:29 +01:00
|
|
|
Graphics::Surface *t1 = loadPNG(Common::String::format("%s_left.png", setup.c_str()));
|
|
|
|
Graphics::Surface *t2 = loadPNG(Common::String::format("%s_right.png", setup.c_str()));
|
2015-08-14 15:16:40 +02:00
|
|
|
g_system->suggestSideTextures(t1, t2);
|
2015-09-21 09:24:27 +02:00
|
|
|
if (t1)
|
|
|
|
t1->free();
|
|
|
|
if (t2)
|
|
|
|
t2->free();
|
2015-08-14 15:16:40 +02:00
|
|
|
delete t1;
|
|
|
|
delete t2;
|
2015-03-05 19:12:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-07-10 20:43:55 +02:00
|
|
|
void GrimEngine::debugLua(const Common::String &str) {
|
|
|
|
lua_dostring(str.c_str());
|
|
|
|
}
|
|
|
|
|
2009-05-25 06:49:57 +00:00
|
|
|
} // end of namespace Grim
|