mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-11 19:54:03 +00:00
366 lines
9.8 KiB
C++
366 lines
9.8 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* 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 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "tetraedge/tetraedge.h"
|
|
#include "tetraedge/detection.h"
|
|
#include "common/scummsys.h"
|
|
#include "common/config-manager.h"
|
|
#include "common/debug-channels.h"
|
|
#include "common/events.h"
|
|
#include "common/system.h"
|
|
#include "common/savefile.h"
|
|
#include "engines/util.h"
|
|
#include "engines/dialogs.h"
|
|
|
|
#include "tetraedge/game/amerzone_game.h"
|
|
#include "tetraedge/game/syberia_game.h"
|
|
#include "tetraedge/game/application.h"
|
|
#include "tetraedge/game/character.h"
|
|
#include "tetraedge/te/te_core.h"
|
|
#include "tetraedge/te/te_renderer.h"
|
|
#include "tetraedge/te/te_resource_manager.h"
|
|
#include "tetraedge/te/te_lua_thread.h"
|
|
#include "tetraedge/te/te_sound_manager.h"
|
|
#include "tetraedge/te/te_input_mgr.h"
|
|
#include "tetraedge/te/te_particle.h"
|
|
|
|
namespace Tetraedge {
|
|
|
|
TetraedgeEngine *g_engine;
|
|
|
|
TetraedgeEngine::TetraedgeEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst),
|
|
_gameDescription(gameDesc), _randomSource("Tetraedge"), _resourceManager(nullptr),
|
|
_core(nullptr), _application(nullptr), _game(nullptr), _renderer(nullptr),
|
|
_soundManager(nullptr), _inputMgr(nullptr), _gameType(kNone) {
|
|
g_engine = this;
|
|
}
|
|
|
|
TetraedgeEngine::~TetraedgeEngine() {
|
|
//TeObject::deleteNow();
|
|
delete _core;
|
|
delete _game;
|
|
delete _application;
|
|
delete _renderer;
|
|
delete _soundManager;
|
|
delete _resourceManager;
|
|
delete _inputMgr;
|
|
Object3D::cleanup();
|
|
Character::cleanup();
|
|
TeAnimation::cleanup();
|
|
TeLuaThread::cleanup();
|
|
TeTimer::cleanup();
|
|
TeObject::cleanup();
|
|
TeParticle::cleanup();
|
|
}
|
|
|
|
/*static*/
|
|
Common::StringArray TetraedgeEngine::splitString(const Common::String &text, char c) {
|
|
Common::StringArray values;
|
|
|
|
Common::String str = text;
|
|
size_t pos;
|
|
while ((pos = str.findFirstOf(c)) != Common::String::npos) {
|
|
values.push_back(Common::String(str.c_str(), pos));
|
|
str = Common::String(str.c_str() + pos + 1);
|
|
}
|
|
|
|
values.push_back(str);
|
|
return values;
|
|
}
|
|
|
|
Application *TetraedgeEngine::getApplication() {
|
|
// created in run()
|
|
return _application;
|
|
}
|
|
|
|
TeCore *TetraedgeEngine::getCore() {
|
|
if (_core == nullptr)
|
|
_core = new TeCore();
|
|
return _core;
|
|
}
|
|
|
|
Game *TetraedgeEngine::getGame() {
|
|
if (_game == nullptr) {
|
|
if (gameIsAmerzone())
|
|
_game = new AmerzoneGame();
|
|
else
|
|
_game = new SyberiaGame();
|
|
}
|
|
return _game;
|
|
}
|
|
|
|
TeSoundManager *TetraedgeEngine::getSoundManager() {
|
|
if (_soundManager == nullptr)
|
|
_soundManager = new TeSoundManager();
|
|
return _soundManager;
|
|
}
|
|
|
|
TeRenderer *TetraedgeEngine::getRenderer() {
|
|
// created in run()
|
|
return _renderer;
|
|
}
|
|
|
|
TeResourceManager *TetraedgeEngine::getResourceManager() {
|
|
if (_resourceManager == nullptr)
|
|
_resourceManager = new TeResourceManager();
|
|
return _resourceManager;
|
|
}
|
|
|
|
TeInputMgr *TetraedgeEngine::getInputMgr() {
|
|
if (_inputMgr == nullptr)
|
|
_inputMgr = new TeInputMgr();
|
|
return _inputMgr;
|
|
}
|
|
|
|
uint32 TetraedgeEngine::getFeatures() const {
|
|
return _gameDescription->flags;
|
|
}
|
|
|
|
Common::String TetraedgeEngine::getGameId() const {
|
|
return _gameDescription->gameId;
|
|
}
|
|
|
|
Common::Language TetraedgeEngine::getGameLanguage() const {
|
|
return _gameDescription->language;
|
|
}
|
|
|
|
Common::Platform TetraedgeEngine::getGamePlatform() const {
|
|
return _gameDescription->platform;
|
|
}
|
|
|
|
bool TetraedgeEngine::isGameDemo() const {
|
|
return (_gameDescription->flags & ADGF_DEMO) != 0;
|
|
}
|
|
|
|
bool TetraedgeEngine::canLoadGameStateCurrently(Common::U32String *msg) {
|
|
return _game && _application && !_application->mainMenu().isEntered();
|
|
}
|
|
|
|
bool TetraedgeEngine::canSaveGameStateCurrently(Common::U32String *msg) {
|
|
return canSaveAutosaveCurrently() && !_application->isLockCursor();
|
|
}
|
|
|
|
bool TetraedgeEngine::canSaveAutosaveCurrently() {
|
|
if (!_game || !_application)
|
|
return false;
|
|
|
|
bool sceneLoaded;
|
|
|
|
if (gameIsAmerzone()) {
|
|
AmerzoneGame *game = dynamic_cast<AmerzoneGame *>(_game);
|
|
assert(game);
|
|
sceneLoaded = (game->warpY() != nullptr);
|
|
} else {
|
|
sceneLoaded = !_game->currentScene().empty() && !_game->currentZone().empty();
|
|
}
|
|
|
|
return _game->running() && sceneLoaded;
|
|
}
|
|
|
|
Common::Error TetraedgeEngine::loadGameState(int slot) {
|
|
// In case autosaves are on, do a save first before loading the new save
|
|
saveAutosaveIfEnabled();
|
|
|
|
Common::String saveStateName = getSaveStateName(slot);
|
|
|
|
Common::InSaveFile *saveFile = getSaveFileManager()->openForLoading(saveStateName);
|
|
|
|
if (!saveFile)
|
|
return Common::kReadingFailed;
|
|
|
|
// The game will reopen the file and do the loading, see Game::initLoadedBackupData
|
|
getGame()->setLoadName(saveStateName);
|
|
|
|
delete saveFile;
|
|
return Common::kNoError;
|
|
}
|
|
|
|
Common::Error TetraedgeEngine::loadGameStream(Common::SeekableReadStream *stream) {
|
|
Common::Serializer s(stream, nullptr);
|
|
Common::Error retval = syncGame(s);
|
|
return retval;
|
|
}
|
|
|
|
void TetraedgeEngine::closeGameDialogs() {
|
|
if (!_game)
|
|
return;
|
|
_game->closeDialogs();
|
|
}
|
|
|
|
void TetraedgeEngine::configureSearchPaths() {
|
|
const Common::FSNode gameDataDir(ConfMan.getPath("path"));
|
|
if (_gameDescription->platform != Common::kPlatformIOS)
|
|
SearchMan.addSubDirectoryMatching(gameDataDir, "Resources", 0, 5);
|
|
}
|
|
|
|
int TetraedgeEngine::getDefaultScreenWidth() const {
|
|
return gameIsAmerzone() ? 1280 : 800;
|
|
}
|
|
|
|
int TetraedgeEngine::getDefaultScreenHeight() const {
|
|
return gameIsAmerzone() ? 800 : 600;
|
|
}
|
|
|
|
bool TetraedgeEngine::onKeyUp(const Common::KeyState &state) {
|
|
switch (state.keycode) {
|
|
case Common::KEYCODE_l:
|
|
if (loadGameDialog())
|
|
_game->initLoadedBackupData();
|
|
break;
|
|
case Common::KEYCODE_s:
|
|
saveGameDialog();
|
|
break;
|
|
case Common::KEYCODE_ESCAPE:
|
|
closeGameDialogs();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void TetraedgeEngine::registerConfigDefaults() {
|
|
// The skips are mostly for debugging to jump straight to certain
|
|
// things. If they are all enabled you get into a new game as
|
|
// soon as possible.
|
|
ConfMan.registerDefault("skip_videos", false);
|
|
ConfMan.registerDefault("skip_splash", false);
|
|
ConfMan.registerDefault("skip_mainmenu", false);
|
|
ConfMan.registerDefault("skip_confirm", false);
|
|
|
|
ConfMan.registerDefault("disable_shadows", false);
|
|
ConfMan.registerDefault("correct_movie_aspect", true);
|
|
ConfMan.registerDefault("restore_scenes", false);
|
|
}
|
|
|
|
|
|
Common::Error TetraedgeEngine::run() {
|
|
if (getGameId() == "syberia")
|
|
_gameType = kSyberia;
|
|
else if (getGameId() == "syberia2")
|
|
_gameType = kSyberia2;
|
|
else if (getGameId() == "amerzone")
|
|
_gameType = kAmerzone;
|
|
else
|
|
error("Unknown game id %s", getGameId().c_str());
|
|
|
|
registerConfigDefaults();
|
|
|
|
configureSearchPaths();
|
|
// from BasicOpenGLView::prepareOpenGL..
|
|
_application = new Application();
|
|
_renderer = TeRenderer::makeInstance();
|
|
_renderer->init(getDefaultScreenWidth(), getDefaultScreenHeight());
|
|
_renderer->reset();
|
|
|
|
getInputMgr()->_keyUpSignal.add(this, &TetraedgeEngine::onKeyUp);
|
|
|
|
// If a savegame was selected from the launcher, load it.
|
|
// Should be before application->create() because it only
|
|
// sets the game name to load inside the Game object. It will
|
|
// actually be loaded when the application is created.
|
|
int saveSlot = ConfMan.getInt("save_slot");
|
|
if (saveSlot != -1)
|
|
(void)loadGameState(saveSlot);
|
|
|
|
_application->create();
|
|
|
|
Common::Event e;
|
|
|
|
while (!shouldQuit()) {
|
|
while (g_system->getEventManager()->pollEvent(e)) {
|
|
getInputMgr()->handleEvent(e);
|
|
}
|
|
|
|
_application->run();
|
|
|
|
g_system->delayMillis(10);
|
|
}
|
|
|
|
// Ensure game has stopped.
|
|
_game->leave(true);
|
|
TeObject::deleteNow();
|
|
_application->destroy();
|
|
|
|
return Common::kNoError;
|
|
}
|
|
|
|
Common::Error TetraedgeEngine::syncGame(Common::Serializer &s) {
|
|
return getGame()->syncGame(s);
|
|
}
|
|
|
|
void TetraedgeEngine::openConfigDialog() {
|
|
GUI::ConfigDialog dlg;
|
|
dlg.runModal();
|
|
|
|
g_system->applyBackendSettings();
|
|
applyGameSettings();
|
|
syncSoundSettings();
|
|
}
|
|
|
|
|
|
Graphics::RendererType TetraedgeEngine::preferredRendererType() const {
|
|
Common::String rendererConfig = ConfMan.get("renderer");
|
|
Graphics::RendererType desiredRendererType = Graphics::Renderer::parseTypeCode(rendererConfig);
|
|
uint32 availableRendererTypes = Graphics::Renderer::getAvailableTypes();
|
|
|
|
availableRendererTypes &=
|
|
#if defined(USE_OPENGL_GAME)
|
|
Graphics::kRendererTypeOpenGL |
|
|
#endif
|
|
#if defined(USE_OPENGL_SHADERS)
|
|
Graphics::kRendererTypeOpenGLShaders |
|
|
#endif
|
|
#if defined(USE_TINYGL)
|
|
Graphics::kRendererTypeTinyGL |
|
|
#endif
|
|
0;
|
|
|
|
Graphics::RendererType matchingRendererType = Graphics::Renderer::getBestMatchingType(desiredRendererType, availableRendererTypes);
|
|
// Currently no difference between shaders and otherwise for this engine.
|
|
if (matchingRendererType == Graphics::kRendererTypeOpenGLShaders)
|
|
matchingRendererType = Graphics::kRendererTypeOpenGL;
|
|
|
|
if (matchingRendererType == 0) {
|
|
error("No supported renderer available.");
|
|
}
|
|
|
|
return matchingRendererType;
|
|
}
|
|
|
|
Common::Error TetraedgeEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
|
|
Common::Error result = Engine::saveGameState(slot, desc, isAutosave);
|
|
if (result.getCode() == Common::kNoError) {
|
|
ConfMan.setInt("last_save_slot", slot);
|
|
ConfMan.flushToDisk();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*static*/
|
|
void TetraedgeEngine::getSavegameThumbnail(Graphics::Surface &thumb) {
|
|
g_engine->getApplication()->getSavegameThumbnail(thumb);
|
|
}
|
|
|
|
|
|
} // namespace Tetraedge
|