diff options
Diffstat (limited to 'engines/fullpipe/gameloader.cpp')
-rw-r--r-- | engines/fullpipe/gameloader.cpp | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/engines/fullpipe/gameloader.cpp b/engines/fullpipe/gameloader.cpp new file mode 100644 index 0000000000..a44501b17d --- /dev/null +++ b/engines/fullpipe/gameloader.cpp @@ -0,0 +1,342 @@ +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "fullpipe/fullpipe.h" + +#include "fullpipe/gameloader.h" +#include "fullpipe/scene.h" +#include "fullpipe/input.h" +#include "fullpipe/statics.h" +#include "fullpipe/interaction.h" + +namespace Fullpipe { + +CInventory2 *getGameLoaderInventory() { + return &g_fullpipe->_gameLoader->_inventory; +} + +CMctlCompound *getSc2MctlCompoundBySceneId(int16 sceneId) { + for (uint i = 0; i < g_fullpipe->_gameLoader->_sc2array.size(); i++) + if (g_fullpipe->_gameLoader->_sc2array[i]._sceneId == sceneId) + return (CMctlCompound *)g_fullpipe->_gameLoader->_sc2array[i]._motionController; + + return 0; +} + +CInteractionController *getGameLoaderInteractionController() { + return g_fullpipe->_gameLoader->_interactionController; +} + +CGameLoader::CGameLoader() { + _interactionController = new CInteractionController(); + _inputController = new CInputController(); + + _gameProject = 0; + _gameName = 0; + + addMessageHandlerByIndex(global_messageHandler2, 0, 0); + insertMessageHandler(global_messageHandler3, 0, 128); + insertMessageHandler(global_messageHandler4, 0, 1); + + _field_FA = 0; + _field_F8 = 0; + _sceneSwitcher = 0; + _preloadCallback = 0; + _readSavegameCallback = 0; + _gameVar = 0; + _preloadSceneId = 0; + _preloadEntranceId = 0; + _updateCounter = 0; + + g_fullpipe->_msgX = 0; + g_fullpipe->_msgY = 0; + g_fullpipe->_msgObjectId2 = 0; + g_fullpipe->_msgId = 0; +} + +CGameLoader::~CGameLoader() { + free(_gameName); + delete _gameProject; + delete _interactionController; + delete _inputController; +} + +bool CGameLoader::load(MfcArchive &file) { + debug(5, "CGameLoader::load()"); + + _gameName = file.readPascalString(); + debug(6, "_gameName: %s", _gameName); + + _gameProject = new GameProject(); + + _gameProject->load(file); + + g_fullpipe->_gameProject = _gameProject; + + if (g_fullpipe->_gameProjectVersion < 12) { + error("Old gameProjectVersion: %d", g_fullpipe->_gameProjectVersion); + } + + _gameName = file.readPascalString(); + debug(6, "_gameName: %s", _gameName); + + _inventory.load(file); + + _interactionController->load(file); + + debug(6, "sceneTag count: %d", _gameProject->_sceneTagList->size()); + + _sc2array.resize(_gameProject->_sceneTagList->size()); + + int i = 0; + for (SceneTagList::const_iterator it = _gameProject->_sceneTagList->begin(); it != _gameProject->_sceneTagList->end(); ++it, i++) { + char tmp[12]; + + snprintf(tmp, 11, "%04d.sc2", it->_sceneId); + + debug(2, "sc: %s", tmp); + + _sc2array[i].loadFile((const char *)tmp); + } + + _preloadItems.load(file); + + _field_FA = file.readUint16LE(); + _field_F8 = file.readUint16LE(); + + _gameVar = (CGameVar *)file.readClass(); + + return true; +} + +bool CGameLoader::loadScene(int sceneId) { + SceneTag *st; + + int idx = getSceneTagBySceneId(sceneId, &st); + + if (idx < 0) + return false; + + if (!st->_scene) + st->loadScene(); + + if (st->_scene) { + st->_scene->init(); + + applyPicAniInfos(st->_scene, _sc2array[idx]._defPicAniInfos, _sc2array[idx]._defPicAniInfosCount); + applyPicAniInfos(st->_scene, _sc2array[idx]._picAniInfos, _sc2array[idx]._picAniInfosCount); + + _sc2array[idx]._scene = st->_scene; + _sc2array[idx]._isLoaded = 1; + + return true; + } + + return false; +} + +bool CGameLoader::gotoScene(int sceneId, int entranceId) { + SceneTag *st; + + int sc2idx = getSceneTagBySceneId(sceneId, &st); + + if (sc2idx < 0) + return false; + + if (!_sc2array[sc2idx]._isLoaded) + return 0; + + if (_sc2array[sc2idx]._entranceDataCount < 1) { + g_fullpipe->_currentScene = st->_scene; + return true; + } + + if (_sc2array[sc2idx]._entranceDataCount <= 0) + return false; + + if (sceneId == 726) + return true; + + int entranceIdx; + for (entranceIdx = 0; _sc2array[sc2idx]._entranceData[entranceIdx]->_field_4 != entranceId; entranceIdx++) { + if (entranceIdx >= _sc2array[sc2idx]._entranceDataCount) + return false; + } + + CGameVar *sg = _gameVar->getSubVarByName("OBJSTATES")->getSubVarByName("SAVEGAME"); + + if (sg || (sg = _gameVar->getSubVarByName("OBJSTATES")->addSubVarAsInt("SAVEGAME", 0)) != 0) + sg->setSubVarAsInt("Entrance", entranceId); + + if (!g_fullpipe->sceneSwitcher(_sc2array[sc2idx]._entranceData[entranceIdx])) + return false; + + g_fullpipe->_msgObjectId2 = 0; + g_fullpipe->_msgY = -1; + g_fullpipe->_msgX = -1; + + g_fullpipe->_currentScene = st->_scene; + + MessageQueue *mq1 = g_fullpipe->_currentScene->getMessageQueueById(_sc2array[sc2idx]._entranceData[entranceIdx]->_messageQueueId); + if (mq1) { + MessageQueue *mq = new MessageQueue(mq1, 0, 0); + + StaticANIObject *stobj = g_fullpipe->_currentScene->getStaticANIObject1ById(_field_FA, -1); + if (stobj) { + stobj->_flags &= 0x100; + + ExCommand *ex = new ExCommand(stobj->_id, 34, 256, 0, 0, 0, 1, 0, 0, 0); + + ex->_field_14 = 256; + ex->_messageNum = 0; + ex->_excFlags |= 3; + + mq->_exCommands.push_back(ex); + } + + mq->setFlags(mq->getFlags() | 1); + + if (!mq->chain(0)) { + delete mq; + + return false; + } + } else { + StaticANIObject *stobj = g_fullpipe->_currentScene->getStaticANIObject1ById(_field_FA, -1); + if (stobj) + stobj->_flags &= 0xfeff; + } + + return true; +} + +bool CGameLoader::preloadScene(int sceneId, int entranceId) { + warning("STUB: preloadScene(%d, %d), ", sceneId, entranceId); + + return true; +} + +int CGameLoader::getSceneTagBySceneId(int sceneId, SceneTag **st) { + if (_sc2array.size() > 0 && _gameProject->_sceneTagList->size() > 0) { + for (uint i = 0; i < _sc2array.size(); i++) { + if (_sc2array[i]._sceneId == sceneId) { + int num = 0; + for (SceneTagList::iterator s = _gameProject->_sceneTagList->begin(); s != _gameProject->_sceneTagList->end(); ++s, num++) { + if (s->_sceneId == sceneId) { + *st = &(*s); + return num; + } + } + } + } + } + + *st = 0; + return -1; +} + +void CGameLoader::applyPicAniInfos(Scene *sc, PicAniInfo **picAniInfo, int picAniInfoCount) { + if (picAniInfoCount <= 0) + return; + + debug(0, "CGameLoader::applyPicAniInfos(sc, ptr, %d)", picAniInfoCount); + + PictureObject *pict; + StaticANIObject *ani; + + for (int i = 0; i < picAniInfoCount; i++) { + debug(7, "PicAniInfo: id: %d type: %d", picAniInfo[i]->objectId, picAniInfo[i]->type); + if (picAniInfo[i]->type & 2) { + pict = sc->getPictureObjectById(picAniInfo[i]->objectId, picAniInfo[i]->field_8); + if (pict) { + pict->setPicAniInfo(picAniInfo[i]); + continue; + } + pict = sc->getPictureObjectById(picAniInfo[i]->objectId, 0); + if (pict) { + PictureObject *pictNew = new PictureObject(pict); + + sc->_picObjList.push_back(pictNew); + pictNew->setPicAniInfo(picAniInfo[i]); + continue; + } + } else { + if (!(picAniInfo[i]->type & 1)) + continue; + + Scene *scNew = g_fullpipe->accessScene(picAniInfo[i]->sceneId); + if (!scNew) + continue; + + ani = sc->getStaticANIObject1ById(picAniInfo[i]->objectId, picAniInfo[i]->field_8); + if (ani) { + ani->setPicAniInfo(picAniInfo[i]); + continue; + } + + ani = scNew->getStaticANIObject1ById(picAniInfo[i]->objectId, 0); + if (ani) { + StaticANIObject *aniNew = new StaticANIObject(ani); + + sc->addStaticANIObject(aniNew, 1); + + aniNew->setPicAniInfo(picAniInfo[i]); + continue; + } + } + } +} + +void CGameLoader::updateSystems(int counterdiff) { + if (g_fullpipe->_currentScene) { + g_fullpipe->_currentScene->update(counterdiff); + + _exCommand._messageKind = 17; + _updateCounter++; + _exCommand._messageNum = 33; + _exCommand._excFlags = 0; + _exCommand.postMessage(); + } + + processMessages(); + + if (_preloadSceneId) { + processMessages(); + preloadScene(_preloadSceneId, _preloadEntranceId); + } +} + +CGameVar *FullpipeEngine::getGameLoaderGameVar() { + if (_gameLoader) + return _gameLoader->_gameVar; + else + return 0; +} + +CInputController *FullpipeEngine::getGameLoaderInputController() { + if (_gameLoader) + return _gameLoader->_inputController; + else + return 0; +} + +} // End of namespace Fullpipe |