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.
|
2006-04-02 14:20:45 +00: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.
|
2006-04-02 14:20:45 +00: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"
|
|
|
|
|
2012-01-24 19:02:50 +01:00
|
|
|
#include "graphics/pixelbuffer.h"
|
|
|
|
|
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
|
|
|
|
2009-05-25 19:21:58 +00:00
|
|
|
#include "engines/engine.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-01-29 16:37:30 +01:00
|
|
|
#include "engines/grim/emi/lua_v2.h"
|
2012-11-12 23:07:32 +01:00
|
|
|
#include "engines/grim/emi/poolsound.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"
|
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 {
|
|
|
|
|
2009-05-17 08:24:17 +00:00
|
|
|
GrimEngine *g_grim = NULL;
|
2009-05-25 19:21:58 +00:00
|
|
|
GfxBase *g_driver = NULL;
|
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) :
|
2011-09-19 16:53:08 +02:00
|
|
|
Engine(syst), _currSet(NULL), _selectedActor(NULL) {
|
2009-05-25 19:21:58 +00:00
|
|
|
g_grim = this;
|
|
|
|
|
2013-02-04 16:37:34 +01:00
|
|
|
_debugger = 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
|
|
|
|
2009-05-25 19:21:58 +00:00
|
|
|
g_registry = new Registry();
|
2009-05-26 06:27:47 +00:00
|
|
|
g_resourceloader = NULL;
|
|
|
|
g_localizer = NULL;
|
2011-05-14 12:11:53 +02:00
|
|
|
g_movie = NULL;
|
2009-05-26 06:27:47 +00:00
|
|
|
g_imuse = NULL;
|
2006-02-05 20:40:16 +00:00
|
|
|
|
2012-03-07 23:02:08 +01:00
|
|
|
_showFps = g_registry->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"));
|
|
|
|
|
2011-09-19 16:53:08 +02:00
|
|
|
_currSet = NULL;
|
2009-05-25 19:21:58 +00:00
|
|
|
_selectedActor = NULL;
|
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;
|
|
|
|
}
|
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;
|
2012-03-07 23:02:08 +01:00
|
|
|
int speed = g_registry->getInt("engine_speed");
|
2009-05-27 07:48:01 +00:00
|
|
|
if (speed <= 0 || speed > 100)
|
2012-08-19 19:45:32 +02:00
|
|
|
_speedLimitMs = 1000 / 60;
|
2008-08-17 05:36:41 +00:00
|
|
|
else
|
|
|
|
_speedLimitMs = 1000 / speed;
|
|
|
|
char buf[20];
|
2008-08-17 07:50:38 +00:00
|
|
|
sprintf(buf, "%d", 1000 / _speedLimitMs);
|
2012-03-07 23:02:08 +01:00
|
|
|
g_registry->setString("engine_speed", buf);
|
2005-08-13 16:25:51 +00:00
|
|
|
_refreshDrawNeeded = true;
|
2011-04-12 20:41:22 +08:00
|
|
|
_listFilesIter = NULL;
|
2005-12-26 02:36:00 +00:00
|
|
|
_savedState = NULL;
|
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);
|
|
|
|
_printLineDefaults.setFont(NULL);
|
|
|
|
_printLineDefaults.setJustify(TextObject::LJUSTIFY);
|
|
|
|
|
|
|
|
_sayLineDefaults.setX(0);
|
|
|
|
_sayLineDefaults.setY(100);
|
|
|
|
_sayLineDefaults.setWidth(0);
|
|
|
|
_sayLineDefaults.setHeight(0);
|
|
|
|
_sayLineDefaults.setFGColor(c);
|
|
|
|
_sayLineDefaults.setFont(NULL);
|
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);
|
|
|
|
_blastTextDefaults.setFont(NULL);
|
|
|
|
_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");
|
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;
|
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;
|
|
|
|
g_registry = NULL;
|
|
|
|
}
|
2011-05-14 12:11:53 +02:00
|
|
|
delete g_movie;
|
|
|
|
g_movie = NULL;
|
2009-05-25 19:21:58 +00:00
|
|
|
delete g_imuse;
|
|
|
|
g_imuse = NULL;
|
2012-01-25 20:35:58 -08:00
|
|
|
delete g_sound;
|
|
|
|
g_sound = NULL;
|
2009-05-25 19:21:58 +00:00
|
|
|
delete g_localizer;
|
|
|
|
g_localizer = NULL;
|
|
|
|
delete g_resourceloader;
|
|
|
|
g_resourceloader = NULL;
|
|
|
|
delete g_driver;
|
|
|
|
g_driver = NULL;
|
2011-07-17 18:17:07 +02:00
|
|
|
delete _iris;
|
2013-02-07 08:12:25 -08:00
|
|
|
delete _debugger;
|
2012-01-31 21:39:34 +01:00
|
|
|
|
|
|
|
DebugMan.clearAllDebugChannels();
|
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();
|
|
|
|
|
|
|
|
_currSet = NULL;
|
|
|
|
}
|
|
|
|
|
2013-02-04 12:46:42 +01:00
|
|
|
void GrimEngine::createRenderer() {
|
|
|
|
#ifdef USE_OPENGL
|
|
|
|
_softRenderer = g_registry->getBool("soft_renderer");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!_softRenderer && !g_system->hasFeature(OSystem::kFeatureOpenGL)){
|
|
|
|
warning("gfx backend doesn't support hardware rendering");
|
|
|
|
_softRenderer = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_softRenderer) {
|
|
|
|
g_driver = CreateGfxTinyGL();
|
|
|
|
#ifdef USE_OPENGL
|
|
|
|
} else {
|
|
|
|
g_driver = CreateGfxOpenGL();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
if (getGameType() == GType_MONKEY4 && 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;
|
|
|
|
}
|
|
|
|
|
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()) {
|
2013-06-26 17:27:26 +02:00
|
|
|
Common::String confirmString("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 ");
|
|
|
|
confirmString += (GType_MONKEY4 == getGameType() ? "Escape From Monkey Island?" : "Grim Fandango?");
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
2011-10-04 18:47:03 +02:00
|
|
|
g_imuse = new Imuse(20, demo);
|
2012-01-25 20:35:58 -08:00
|
|
|
g_sound = new SoundPlayer();
|
2009-05-26 06:27:47 +00:00
|
|
|
|
2012-03-07 23:02:08 +01:00
|
|
|
bool fullscreen = g_registry->getBool("fullscreen");
|
2013-02-04 12:46:42 +01:00
|
|
|
createRenderer();
|
2009-05-31 08:55:57 +00:00
|
|
|
g_driver->setupScreen(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")) {
|
|
|
|
// TODO: Play EMI Mac Aspyr logo
|
|
|
|
warning("TODO: Play Aspyr logo");
|
|
|
|
}
|
|
|
|
|
2011-09-10 20:47:07 +02:00
|
|
|
Bitmap *splash_bm = NULL;
|
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();
|
|
|
|
|
2012-01-14 13:21:43 +01:00
|
|
|
if (splash_bm != NULL)
|
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
|
|
|
|
2011-10-12 17:42:40 +02:00
|
|
|
LuaBase *lua = NULL;
|
2011-05-08 07:28:46 +02:00
|
|
|
if (getGameType() == GType_GRIM) {
|
2011-10-13 15:41:22 +02:00
|
|
|
lua = new Lua_V1();
|
2011-10-12 17:42:40 +02:00
|
|
|
} else {
|
2011-10-13 15:41:22 +02:00
|
|
|
lua = new Lua_V2();
|
2011-10-12 17:42:40 +02:00
|
|
|
}
|
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
|
|
|
|
|
|
|
lua->loadSystemScript();
|
2012-04-06 12:55:53 -07:00
|
|
|
g_localizer = new Localizer();
|
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);
|
2011-09-10 20:47:07 +02:00
|
|
|
if (splash_bm)
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2012-03-26 20:28:31 -07:00
|
|
|
Common::Error GrimEngine::loadGameState(int slot) {
|
|
|
|
assert(slot >= 0);
|
2013-06-27 00:07:57 +02:00
|
|
|
if (getGameType() == GType_MONKEY4) {
|
|
|
|
_savegameFileName = Common::String::format("efmi%03d.gsv",slot);
|
|
|
|
} else {
|
|
|
|
_savegameFileName = Common::String::format("grim%02d.gsv",slot);
|
|
|
|
}
|
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() {
|
2008-07-13 10:53:39 +00:00
|
|
|
void *resource = NULL;
|
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"))
|
|
|
|
resource = (void *)g_resourceloader->loadCostume(buf, NULL);
|
|
|
|
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")) {
|
|
|
|
g_imuse->startSfx(buf);
|
|
|
|
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");
|
2009-06-26 16:13:11 +00:00
|
|
|
resource = (void *)g_resourceloader->loadMaterial(buf, cmap);
|
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
|
|
|
|
2009-05-17 08:12:05 +00:00
|
|
|
void GrimEngine::drawPrimitives() {
|
2011-07-26 00:15:48 +02:00
|
|
|
_iris->draw();
|
2011-07-24 11:47:44 +02:00
|
|
|
|
2011-07-26 00:15:48 +02:00
|
|
|
// Draw text
|
2012-03-21 18:14:58 +01:00
|
|
|
if (_mode == SmushMode) {
|
|
|
|
if (_movieSubtitle) {
|
|
|
|
_movieSubtitle->draw();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
foreach (TextObject *t, TextObject::getPool()) {
|
|
|
|
t->draw();
|
|
|
|
}
|
2011-07-26 00:15:48 +02:00
|
|
|
}
|
2005-08-14 13:26:37 +00:00
|
|
|
}
|
2005-08-13 13:35:43 +00:00
|
|
|
|
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
|
2011-11-21 22:07:12 +01:00
|
|
|
foreach (PrimitiveObject *p, PrimitiveObject::getPool()) {
|
|
|
|
p->draw();
|
2011-07-26 00:10:27 +02:00
|
|
|
}
|
2005-08-28 23:25:14 +00:00
|
|
|
drawPrimitives();
|
2012-02-18 22:20:16 +01:00
|
|
|
} else if (_mode == NormalMode || _mode == OverworldMode) {
|
2011-09-19 16:53:08 +02:00
|
|
|
if (!_currSet)
|
2005-08-13 16:25:51 +00:00
|
|
|
return;
|
|
|
|
|
2008-09-26 11:57:56 +00:00
|
|
|
g_driver->clearScreen();
|
2005-08-13 16:25:51 +00:00
|
|
|
|
2005-08-13 13:35:43 +00:00
|
|
|
_prevSmushFrame = 0;
|
2011-06-06 04:26:18 +08:00
|
|
|
_movieTime = 0;
|
2005-08-13 16:25:51 +00:00
|
|
|
|
2011-09-19 16:53:08 +02:00
|
|
|
_currSet->drawBackground();
|
2005-08-13 16:25:51 +00:00
|
|
|
|
|
|
|
// 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
|
2011-09-19 16:53:08 +02:00
|
|
|
_currSet->drawBitmaps(ObjectState::OBJSTATE_BACKGROUND);
|
2009-06-07 20:23:28 +00:00
|
|
|
|
2005-08-13 16:25:51 +00:00
|
|
|
// State objects are drawn on top of other things, such as the flag
|
|
|
|
// on Manny's message tube
|
2011-09-19 16:53:08 +02:00
|
|
|
_currSet->drawBitmaps(ObjectState::OBJSTATE_STATE);
|
2005-08-13 16:25:51 +00:00
|
|
|
|
|
|
|
// 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
|
2013-01-08 00:33:59 +01:00
|
|
|
if (g_movie->isPlaying() && _movieSetup == _currSet->getCurrSetup()->_name) {
|
2011-05-14 12:11:53 +02:00
|
|
|
_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 16:25:51 +00:00
|
|
|
}
|
2011-10-05 19:06:18 +02:00
|
|
|
if (g_movie->getFrame() >= 0)
|
2011-08-14 18:35:49 +02:00
|
|
|
g_driver->drawMovieFrame(g_movie->getX(), g_movie->getY());
|
2008-08-12 14:55:16 +00:00
|
|
|
else
|
2011-08-14 18:35:49 +02:00
|
|
|
g_driver->releaseMovieFrame();
|
2005-08-13 16:25:51 +00:00
|
|
|
}
|
|
|
|
|
2012-08-19 18:58:08 +02: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);
|
|
|
|
|
2011-07-26 00:10:27 +02:00
|
|
|
// Draw Primitives
|
2011-11-21 22:07:12 +01:00
|
|
|
foreach (PrimitiveObject *p, PrimitiveObject::getPool()) {
|
|
|
|
p->draw();
|
2011-07-26 00:10:27 +02:00
|
|
|
}
|
|
|
|
|
2011-09-19 16:53:08 +02:00
|
|
|
_currSet->setupCamera();
|
2005-08-13 16:25:51 +00:00
|
|
|
|
|
|
|
g_driver->set3DMode();
|
|
|
|
|
2012-02-13 18:01:03 +01:00
|
|
|
if (_setupChanged) {
|
|
|
|
cameraPostChangeHandle(_currSet->getSetup());
|
|
|
|
_setupChanged = false;
|
|
|
|
}
|
|
|
|
|
2005-08-13 16:25:51 +00:00
|
|
|
// Draw actors
|
2012-02-24 17:11:55 +01:00
|
|
|
buildActiveActorsList();
|
2012-11-21 22:32:46 +01:00
|
|
|
if (g_grim->getGameType() == GType_GRIM) {
|
|
|
|
foreach (Actor *a, _activeActors) {
|
|
|
|
if (a->isVisible())
|
|
|
|
a->draw();
|
|
|
|
}
|
|
|
|
} else {
|
EMI: Draw background layers at intervals
Previously, we split the background layers into everything
before SO 15 and after, and drew like that. However, this caused
the pink ship in shi.setb to not be drawn.
This patch draws the layers of the background at intervals of ten.
So if a set has six layers, layer 5 is the background and 4,3,2,1,0
are rendered at sortorder 40,30,20,10,0.
2013-06-29 14:36:17 +02:00
|
|
|
Bitmap *background = _currSet->_currSetup->_bkgndBm;
|
|
|
|
uint32 numLayers = background->_data->_numLayers;
|
|
|
|
int32 currentLayer = numLayers - 1;
|
2012-11-21 22:32:46 +01:00
|
|
|
foreach (Actor *a, _activeActors) {
|
EMI: Draw background layers at intervals
Previously, we split the background layers into everything
before SO 15 and after, and drew like that. However, this caused
the pink ship in shi.setb to not be drawn.
This patch draws the layers of the background at intervals of ten.
So if a set has six layers, layer 5 is the background and 4,3,2,1,0
are rendered at sortorder 40,30,20,10,0.
2013-06-29 14:36:17 +02:00
|
|
|
if (a->getSortOrder() < 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
while (a->getSortOrder() < currentLayer * 10 && currentLayer >= 0) {
|
|
|
|
background->drawLayer(currentLayer--);
|
2012-11-21 22:32:46 +01:00
|
|
|
}
|
EMI: Draw background layers at intervals
Previously, we split the background layers into everything
before SO 15 and after, and drew like that. However, this caused
the pink ship in shi.setb to not be drawn.
This patch draws the layers of the background at intervals of ten.
So if a set has six layers, layer 5 is the background and 4,3,2,1,0
are rendered at sortorder 40,30,20,10,0.
2013-06-29 14:36:17 +02:00
|
|
|
|
2012-11-21 22:32:46 +01:00
|
|
|
if (a->isVisible() && a->getSortOrder() < 100)
|
|
|
|
a->draw();
|
|
|
|
}
|
2012-02-24 17:11:55 +01:00
|
|
|
}
|
2012-03-04 18:16:37 +01:00
|
|
|
|
2012-11-21 22:32:46 +01:00
|
|
|
|
2008-07-05 08:48:39 +00:00
|
|
|
flagRefreshShadowMask(false);
|
2005-08-13 16:25:51 +00: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
|
2011-09-19 16:53:08 +02:00
|
|
|
_currSet->drawBitmaps(ObjectState::OBJSTATE_OVERLAY);
|
2005-08-13 20:14:46 +00:00
|
|
|
|
2013-01-11 12:39:12 +01:00
|
|
|
g_driver->drawBuffers();
|
2005-08-28 23:25:14 +00:00
|
|
|
drawPrimitives();
|
2011-10-04 22:01:24 +02:00
|
|
|
} else if (_mode == DrawMode) {
|
2011-12-18 22:25:47 +01:00
|
|
|
_doFlip = false;
|
2011-06-06 04:26:18 +08:00
|
|
|
_prevSmushFrame = 0;
|
|
|
|
_movieTime = 0;
|
2005-08-13 13:35:43 +00:00
|
|
|
}
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
|
|
|
sprintf(_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();
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2012-01-31 11:15:19 +01:00
|
|
|
bool fullscreen = g_driver->isFullscreen();
|
2012-01-29 10:28:20 +01:00
|
|
|
if (_changeFullscreenState) {
|
|
|
|
fullscreen = !fullscreen;
|
|
|
|
}
|
|
|
|
g_system->setFeatureState(OSystem::kFeatureFullscreenMode, fullscreen);
|
2012-03-07 23:02:08 +01:00
|
|
|
g_registry->setBool("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;
|
2013-02-04 12:46:42 +01:00
|
|
|
createRenderer();
|
2012-01-29 10:44:11 +01:00
|
|
|
g_driver->setupScreen(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
|
|
|
}
|
|
|
|
|
2005-08-13 13:35:43 +00:00
|
|
|
g_imuse->flushTracks();
|
|
|
|
g_imuse->refreshScripts();
|
|
|
|
|
2013-02-04 16:37:34 +01:00
|
|
|
_debugger->onFrame();
|
|
|
|
|
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) {
|
|
|
|
if (_mode != DrawMode && _mode != SmushMode && (event.kbd.ascii == 'q')) {
|
|
|
|
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
|
|
|
|
|
|
|
// 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()
|
|
|
|
luaUpdate();
|
2009-05-31 16:09:21 +00:00
|
|
|
}
|
2011-10-13 20:25:50 +02:00
|
|
|
if (type == Common::EVENT_SCREEN_CHANGED)
|
2005-08-20 18:54:17 +00:00
|
|
|
_refreshDrawNeeded = true;
|
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();
|
|
|
|
}
|
|
|
|
|
2005-08-13 13:35:43 +00:00
|
|
|
luaUpdate();
|
2004-11-01 16:36:41 +00:00
|
|
|
|
2011-10-04 22:01:24 +02:00
|
|
|
if (_mode != PauseMode) {
|
2005-08-28 23:25:14 +00:00
|
|
|
doFlip();
|
2004-04-15 20:39:09 +00:00
|
|
|
}
|
2004-10-31 09:31:34 +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;
|
2004-12-30 22:38:53 +00:00
|
|
|
g_imuse->stopAllSounds();
|
2004-12-30 23:48:04 +00:00
|
|
|
g_imuse->resetState();
|
2011-05-14 12:11:53 +02:00
|
|
|
g_movie->stop();
|
2005-01-14 10:53:29 +00:00
|
|
|
g_imuse->pause(true);
|
2011-05-14 12:11:53 +02:00
|
|
|
g_movie->pause(true);
|
2013-01-18 17:39:04 +01:00
|
|
|
g_registry->save();
|
2005-01-14 10:53:29 +00:00
|
|
|
|
2011-03-21 05:16:27 +08:00
|
|
|
_selectedActor = NULL;
|
2011-09-19 16:53:08 +02:00
|
|
|
delete _currSet;
|
|
|
|
_currSet = NULL;
|
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.");
|
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
|
|
|
|
2005-12-26 02:36:00 +00:00
|
|
|
g_imuse->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();
|
2005-01-14 10:53:29 +00:00
|
|
|
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
|
|
|
|
|
|
|
g_driver->refreshBuffers();
|
|
|
|
_currSet->setupCamera();
|
|
|
|
g_driver->set3DMode();
|
|
|
|
foreach (Actor *a, Actor::getPool()) {
|
|
|
|
a->restoreCleanBuffer();
|
|
|
|
}
|
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) {
|
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
|
|
|
|
2011-10-04 22:01:24 +02:00
|
|
|
EngineMode mode = g_grim->getMode();
|
2011-08-27 19:09:06 +02:00
|
|
|
g_grim->setMode(_previousMode);
|
2009-05-17 08:24:17 +00:00
|
|
|
g_grim->updateDisplayScene();
|
2011-05-21 03:17:51 +08:00
|
|
|
g_driver->storeDisplay();
|
2006-05-14 07:51:41 +00:00
|
|
|
screenshot = g_driver->getScreenshot(width, height);
|
2009-05-17 08:24:17 +00:00
|
|
|
g_grim->setMode(mode);
|
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);
|
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!
|
|
|
|
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);
|
|
|
|
|
2005-01-14 10:51:20 +00:00
|
|
|
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.");
|
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
|
|
|
|
2005-12-26 02:36:00 +00:00
|
|
|
g_imuse->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
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
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());
|
|
|
|
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
|
|
|
|
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();
|
2013-01-11 12:39:12 +01:00
|
|
|
a->clearCleanBuffer();
|
2011-07-26 16:07:38 +02:00
|
|
|
}
|
2013-01-11 12:39:12 +01:00
|
|
|
g_driver->refreshBuffers();
|
2011-07-26 16:07:38 +02:00
|
|
|
|
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) {
|
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()) {
|
2012-03-25 16:47:22 -07:00
|
|
|
if ((_mode == NormalMode && a->isInSet(_currSet->getName())) || a->isInOverworld()) {
|
2012-07-12 19:18:21 +02:00
|
|
|
if (getGameType() == GType_MONKEY4) {
|
|
|
|
Common::List<Actor *>::iterator it = _activeActors.begin();
|
|
|
|
for (; it != _activeActors.end(); ++it) {
|
|
|
|
if (a->getSortOrder() >= (*it)->getSortOrder())
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
_activeActors.insert(it, a);
|
|
|
|
} else {
|
|
|
|
_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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
(f == kSupportsRTL) ||
|
|
|
|
(f == kSupportsLoadingDuringRuntime);
|
2012-01-31 21:39:34 +01:00
|
|
|
}
|
|
|
|
|
2012-04-30 15:14:14 +02:00
|
|
|
void GrimEngine::openMainMenuDialog() {
|
|
|
|
Common::KeyState key(Common::KEYCODE_F1, Common::ASCII_F1);
|
|
|
|
handleControls(Common::EVENT_KEYDOWN, key);
|
|
|
|
handleControls(Common::EVENT_KEYUP, key);
|
|
|
|
}
|
|
|
|
|
2013-02-07 17:08:11 +01:00
|
|
|
void GrimEngine::pauseEngineIntern(bool pause) {
|
|
|
|
g_imuse->pause(pause);
|
|
|
|
g_movie->pause(pause);
|
|
|
|
}
|
|
|
|
|
2009-05-25 06:49:57 +00:00
|
|
|
} // end of namespace Grim
|