diff options
| author | uruk | 2014-05-30 11:14:47 +0200 |
|---|---|---|
| committer | uruk | 2014-05-30 11:14:47 +0200 |
| commit | bb2f8dd68e1d6b2b30b07f60c0cd4e125b47ea4d (patch) | |
| tree | 9a1e28cfb1eb1a322225c05adc0962a2f96ea521 /engines/fullpipe | |
| parent | 5ad4e157e5398347651a0da0db07f9daf01bf373 (diff) | |
| parent | 0a46d67baea121bed0511ce45bfdd8438a43d35d (diff) | |
| download | scummvm-rg350-bb2f8dd68e1d6b2b30b07f60c0cd4e125b47ea4d.tar.gz scummvm-rg350-bb2f8dd68e1d6b2b30b07f60c0cd4e125b47ea4d.tar.bz2 scummvm-rg350-bb2f8dd68e1d6b2b30b07f60c0cd4e125b47ea4d.zip | |
Merge branch 'master' of https://github.com/scummvm/scummvm into cge2
Diffstat (limited to 'engines/fullpipe')
| -rw-r--r-- | engines/fullpipe/console.cpp | 6 | ||||
| -rw-r--r-- | engines/fullpipe/detection.cpp | 64 | ||||
| -rw-r--r-- | engines/fullpipe/fullpipe.cpp | 52 | ||||
| -rw-r--r-- | engines/fullpipe/fullpipe.h | 1 | ||||
| -rw-r--r-- | engines/fullpipe/gameloader.cpp | 45 | ||||
| -rw-r--r-- | engines/fullpipe/gameloader.h | 16 | ||||
| -rw-r--r-- | engines/fullpipe/gfx.cpp | 25 | ||||
| -rw-r--r-- | engines/fullpipe/gfx.h | 9 | ||||
| -rw-r--r-- | engines/fullpipe/messagehandlers.cpp | 6 | ||||
| -rw-r--r-- | engines/fullpipe/messages.cpp | 15 | ||||
| -rw-r--r-- | engines/fullpipe/modal.cpp | 185 | ||||
| -rw-r--r-- | engines/fullpipe/modal.h | 18 | ||||
| -rw-r--r-- | engines/fullpipe/motion.cpp | 866 | ||||
| -rw-r--r-- | engines/fullpipe/motion.h | 74 | ||||
| -rw-r--r-- | engines/fullpipe/scene.cpp | 106 | ||||
| -rw-r--r-- | engines/fullpipe/scene.h | 11 | ||||
| -rw-r--r-- | engines/fullpipe/scenes.cpp | 29 | ||||
| -rw-r--r-- | engines/fullpipe/sound.cpp | 82 | ||||
| -rw-r--r-- | engines/fullpipe/stateloader.cpp | 5 | ||||
| -rw-r--r-- | engines/fullpipe/statics.cpp | 126 | ||||
| -rw-r--r-- | engines/fullpipe/statics.h | 7 | ||||
| -rw-r--r-- | engines/fullpipe/utils.h | 3 |
22 files changed, 1529 insertions, 222 deletions
diff --git a/engines/fullpipe/console.cpp b/engines/fullpipe/console.cpp index cb76345d66..dd3d1bf693 100644 --- a/engines/fullpipe/console.cpp +++ b/engines/fullpipe/console.cpp @@ -28,14 +28,14 @@ namespace Fullpipe { Console::Console(FullpipeEngine *vm) : GUI::Debugger(), _vm(vm) { - DCmd_Register("scene", WRAP_METHOD(Console, Cmd_Scene)); + registerCmd("scene", WRAP_METHOD(Console, Cmd_Scene)); } bool Console::Cmd_Scene(int argc, const char **argv) { if (argc != 2) { int sceneTag = _vm->_currentScene->_sceneId; - DebugPrintf("Current scene: %d (scene tag: %d)\n", _vm->getSceneFromTag(sceneTag), sceneTag); - DebugPrintf("Use %s <scene> to change the current scene\n", argv[0]); + debugPrintf("Current scene: %d (scene tag: %d)\n", _vm->getSceneFromTag(sceneTag), sceneTag); + debugPrintf("Use %s <scene> to change the current scene\n", argv[0]); return true; } else { int scene = _vm->convertScene(atoi(argv[1])); diff --git a/engines/fullpipe/detection.cpp b/engines/fullpipe/detection.cpp index 62c5dd3b80..de0ed04d25 100644 --- a/engines/fullpipe/detection.cpp +++ b/engines/fullpipe/detection.cpp @@ -26,6 +26,7 @@ #include "common/file.h" #include "fullpipe/fullpipe.h" +#include "fullpipe/gameloader.h" namespace Fullpipe { @@ -87,15 +88,72 @@ public: } virtual bool hasFeature(MetaEngineFeature f) const; + virtual int getMaximumSaveSlot() const { return 8; } + virtual SaveStateList listSaves(const char *target) const; + virtual void removeSaveState(const char *target, int slot) const; + virtual SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const; virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; }; bool FullpipeMetaEngine::hasFeature(MetaEngineFeature f) const { - return false; + return + (f == kSupportsListSaves) || + (f == kSupportsDeleteSave) || + (f == kSavesSupportMetaInfo) || + (f == kSavesSupportThumbnail) || + (f == kSavesSupportCreationDate) || + (f == kSupportsLoadingDuringStartup); } -bool Fullpipe::FullpipeEngine::hasFeature(EngineFeature f) const { - return false; +SaveStateList FullpipeMetaEngine::listSaves(const char *target) const { + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::StringArray filenames; + Common::String pattern("fullpipe.s??"); + + filenames = saveFileMan->listSavefiles(pattern); + sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..) + + SaveStateList saveList; + for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { + // Obtain the last 2 digits of the filename, since they correspond to the save slot + int slotNum = atoi(file->c_str() + file->size() - 2); + + if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) { + Common::InSaveFile *in = saveFileMan->openForLoading(*file); + if (in) { + Fullpipe::FullpipeSavegameHeader header; + Fullpipe::readSavegameHeader(in, header); + saveList.push_back(SaveStateDescriptor(slotNum, header.saveName)); + delete header.thumbnail; + delete in; + } + } + } + + return saveList; +} + +void FullpipeMetaEngine::removeSaveState(const char *target, int slot) const { + g_system->getSavefileManager()->removeSavefile(Fullpipe::getSavegameFile(slot)); +} + +SaveStateDescriptor FullpipeMetaEngine::querySaveMetaInfos(const char *target, int slot) const { + Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading( + Fullpipe::getSavegameFile(slot)); + + if (f) { + Fullpipe::FullpipeSavegameHeader header; + Fullpipe::readSavegameHeader(f, header); + delete f; + + // Create the return descriptor + SaveStateDescriptor desc(slot, header.saveName); + desc.setThumbnail(header.thumbnail); + + return desc; + } + + return SaveStateDescriptor(); } bool FullpipeMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp index 5369c05de7..85a5167841 100644 --- a/engines/fullpipe/fullpipe.cpp +++ b/engines/fullpipe/fullpipe.cpp @@ -37,6 +37,7 @@ #include "fullpipe/scenes.h" #include "fullpipe/floaters.h" #include "fullpipe/console.h" +#include "fullpipe/constants.h" namespace Fullpipe { @@ -205,7 +206,39 @@ void FullpipeEngine::initialize() { } void FullpipeEngine::restartGame() { - warning("STUB: FullpipeEngine::restartGame()"); + _floaters->stopAll(); + + clearGlobalMessageQueueList(); + clearMessages(); + + initObjectStates(); + + if (_scene2) { + _scene2->getAniMan(); + _scene2 = 0; + } + + if (_currentScene) { + _gameLoader->unloadScene(_currentScene->_sceneId); + + _currentScene = 0; + } + + _gameLoader->restoreDefPicAniInfos(); + + getGameLoaderInventory()->clear(); + getGameLoaderInventory()->addItem(ANI_INV_MAP, 1); + getGameLoaderInventory()->rebuildItemRects(); + + initMap(); + + if (_flgPlayIntro) { + _gameLoader->loadScene(SC_INTRO1); + _gameLoader->gotoScene(SC_INTRO1, TrubaUp); + } else { + _gameLoader->loadScene(SC_1); + _gameLoader->gotoScene(SC_1, TrubaLeft); + } } Common::Error FullpipeEngine::run() { @@ -347,7 +380,7 @@ void FullpipeEngine::updateEvents() { case Common::EVENT_QUIT: _gameContinue = false; break; - case Common::EVENT_RBUTTONDOWN: + case Common::EVENT_RBUTTONDOWN: if (!_inputArFlag && (_updateTicks - _lastInputTicks) >= 2) { ex = new ExCommand(0, 17, 107, event.mouse.x, event.mouse.y, 0, 1, 0, 0, 0); ex->_excFlags |= 3; @@ -477,7 +510,20 @@ void FullpipeEngine::setObjectState(const char *name, int state) { } void FullpipeEngine::disableSaves(ExCommand *ex) { - warning("STUB: FullpipeEngine::disableSaves()"); + if (_isSaveAllowed) { + _isSaveAllowed = false; + + if (_globalMessageQueueList->size() && (*_globalMessageQueueList)[0] != 0) { + for (int i = 0; i < _globalMessageQueueList->size(); i++) { + if ((*_globalMessageQueueList)[i]->_flags & 1) + if ((*_globalMessageQueueList)[i]->_id != ex->_parId && !(*_globalMessageQueueList)[i]->_isFinished) + return; + } + } + + if (_currentScene) + _gameLoader->writeSavegame(_currentScene, "savetmp.sav"); + } } diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h index 27505252ab..afdc493258 100644 --- a/engines/fullpipe/fullpipe.h +++ b/engines/fullpipe/fullpipe.h @@ -99,7 +99,6 @@ public: const ADGameDescription *_gameDescription; const char *getGameId() const; Common::Platform getPlatform() const; - bool hasFeature(EngineFeature f) const; Common::RandomSource *_rnd; diff --git a/engines/fullpipe/gameloader.cpp b/engines/fullpipe/gameloader.cpp index d9f7327a6b..c8b01939dd 100644 --- a/engines/fullpipe/gameloader.cpp +++ b/engines/fullpipe/gameloader.cpp @@ -21,6 +21,7 @@ */ #include "fullpipe/fullpipe.h" +#include "graphics/thumbnail.h" #include "fullpipe/gameloader.h" #include "fullpipe/scene.h" @@ -501,6 +502,14 @@ void GameLoader::updateSystems(int counterdiff) { } } +void GameLoader::readSavegame(const char *fname) { + warning("STUB: readSavegame(%s)", fname); +} + +void GameLoader::writeSavegame(Scene *sc, const char *fname) { + warning("STUB: writeSavegame(sc, %s)", fname); +} + Sc2::Sc2() { _sceneId = 0; _field_2 = 0; @@ -593,6 +602,42 @@ bool PreloadItems::load(MfcArchive &file) { return true; } +const char *getSavegameFile(int saveGameIdx) { + static char buffer[20]; + sprintf(buffer, "fullpipe.s%02d", saveGameIdx); + return buffer; +} + +bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header) { + char saveIdentBuffer[6]; + header.thumbnail = NULL; + + // Validate the header Id + in->read(saveIdentBuffer, 6); + if (strcmp(saveIdentBuffer, "SVMCR")) + return false; + + header.version = in->readByte(); + if (header.version != FULLPIPE_SAVEGAME_VERSION) + return false; + + // Read in the string + header.saveName.clear(); + char ch; + while ((ch = (char)in->readByte()) != '\0') header.saveName += ch; + + // Get the thumbnail + header.thumbnail = Graphics::loadThumbnail(*in); + if (!header.thumbnail) + return false; + + return true; +} + +void GameLoader::restoreDefPicAniInfos() { + warning("STUB: restoreDefPicAniInfos()"); +} + GameVar *FullpipeEngine::getGameLoaderGameVar() { if (_gameLoader) return _gameLoader->_gameVar; diff --git a/engines/fullpipe/gameloader.h b/engines/fullpipe/gameloader.h index a79c0e11b4..772cc51130 100644 --- a/engines/fullpipe/gameloader.h +++ b/engines/fullpipe/gameloader.h @@ -29,6 +29,8 @@ namespace Fullpipe { +#define FULLPIPE_SAVEGAME_VERSION 1 + class SceneTag; class MctlCompound; class InputController; @@ -72,6 +74,12 @@ class PreloadItems : public Common::Array<PreloadItem *>, public CObject { virtual bool load(MfcArchive &file); }; +struct FullpipeSavegameHeader { + uint8 version; + Common::String saveName; + Graphics::Surface *thumbnail; +}; + class GameLoader : public CObject { public: GameLoader(); @@ -89,6 +97,11 @@ class GameLoader : public CObject { void applyPicAniInfos(Scene *sc, PicAniInfo **picAniInfo, int picAniInfoCount); void saveScenePicAniInfos(int sceneId); + void readSavegame(const char *fname); + void writeSavegame(Scene *sc, const char *fname); + + void restoreDefPicAniInfos(); + GameProject *_gameProject; InteractionController *_interactionController; InputController *_inputController; @@ -108,6 +121,9 @@ class GameLoader : public CObject { int _preloadEntranceId; }; +const char *getSavegameFile(int saveGameIdx); +bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header); + Inventory2 *getGameLoaderInventory(); InteractionController *getGameLoaderInteractionController(); MctlCompound *getSc2MctlCompoundBySceneId(int16 sceneId); diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp index 7c66a9a747..520e81835b 100644 --- a/engines/fullpipe/gfx.cpp +++ b/engines/fullpipe/gfx.cpp @@ -145,7 +145,7 @@ void Background::addPictureObject(PictureObject *pct) { bool inserted = false; for (uint i = 1; i < _picObjList.size(); i++) { - if (((PictureObject *)_picObjList[i])->_priority <= pct->_priority) { + if (_picObjList[i]->_priority <= pct->_priority) { _picObjList.insert_at(i, pct); inserted = true; break; @@ -192,7 +192,7 @@ bool PictureObject::load(MfcArchive &file, bool bigPicture) { _picture->load(file); - _pictureObject2List = new PtrList(); + _pictureObject2List = new Common::Array<GameObject *>; int count = file.readUint16LE(); @@ -351,7 +351,25 @@ void GameObject::setOXY(int x, int y) { _oy = y; } -void GameObject::renumPictures(PtrList *lst) { +void GameObject::renumPictures(Common::Array<StaticANIObject *> *lst) { + int *buf = (int *)calloc(lst->size() + 2, sizeof(int)); + + for (uint i = 0; i < lst->size(); i++) { + if (_id == ((GameObject *)((*lst)[i]))->_id) + buf[((GameObject *)((*lst)[i]))->_okeyCode] = 1; + } + + if (buf[_okeyCode]) { + uint count; + for (count = 1; buf[count] && count < lst->size() + 2; count++) + ; + _okeyCode = count; + } + + free(buf); +} + +void GameObject::renumPictures(Common::Array<PictureObject *> *lst) { int *buf = (int *)calloc(lst->size() + 2, sizeof(int)); for (uint i = 0; i < lst->size(); i++) { @@ -380,6 +398,7 @@ bool GameObject::getPicAniInfo(PicAniInfo *info) { info->ox = _ox; info->oy = _oy; info->priority = _priority; + warning("Yep %d", _id); return true; } diff --git a/engines/fullpipe/gfx.h b/engines/fullpipe/gfx.h index b3e22b610b..191df7709a 100644 --- a/engines/fullpipe/gfx.h +++ b/engines/fullpipe/gfx.h @@ -92,7 +92,7 @@ class Picture : public MemoryObject { virtual bool load(MfcArchive &file); void setAOIDs(); - void init(); + virtual void init(); void getDibInfo(); Bitmap *getPixelData(); virtual void draw(int x, int y, int style, int angle); @@ -141,7 +141,8 @@ class GameObject : public CObject { virtual bool load(MfcArchive &file); void setOXY(int x, int y); - void renumPictures(PtrList *lst); + void renumPictures(Common::Array<StaticANIObject *> *lst); + void renumPictures(Common::Array<PictureObject *> *lst); void setFlags(int16 flags) { _flags = flags; } void clearFlags() { _flags = 0; } const char *getName() { return _objectName; } @@ -153,7 +154,7 @@ class GameObject : public CObject { class PictureObject : public GameObject { public: Picture *_picture; - PtrList *_pictureObject2List; + Common::Array<GameObject *> *_pictureObject2List; int _ox2; int _oy2; @@ -178,7 +179,7 @@ class PictureObject : public GameObject { class Background : public CObject { public: - PtrList _picObjList; + Common::Array<PictureObject *> _picObjList; char *_bgname; int _x; diff --git a/engines/fullpipe/messagehandlers.cpp b/engines/fullpipe/messagehandlers.cpp index 15aa78d342..d4f79d1dd8 100644 --- a/engines/fullpipe/messagehandlers.cpp +++ b/engines/fullpipe/messagehandlers.cpp @@ -392,12 +392,10 @@ int global_messageHandler3(ExCommand *cmd) { } return result; case 29: - if (!g_fp->_currentScene) - return result; - - if (g_fp->_gameLoader->_interactionController->_flag24) { + if (g_fp->_gameLoader->_interactionController->_flag24 && g_fp->_currentScene) { ani = g_fp->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY); ani2 = g_fp->_currentScene->getStaticANIObject1ById(g_fp->_gameLoader->_field_FA, -1); + if (ani) { if (g_fp->_msgObjectId2 == ani->_id && g_fp->_msgId == ani->_okeyCode) { cmd->_messageKind = 0; diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp index 8257d1459f..b643ff9b8f 100644 --- a/engines/fullpipe/messages.cpp +++ b/engines/fullpipe/messages.cpp @@ -26,6 +26,7 @@ #include "fullpipe/messages.h" #include "fullpipe/modal.h" #include "fullpipe/statics.h" +#include "fullpipe/gameloader.h" namespace Fullpipe { @@ -394,8 +395,18 @@ void MessageQueue::update() { } void MessageQueue::messageQueueCallback1(int par) { - // Autosave - debug(3, "STUB: MessageQueue::messageQueueCallback1()"); + if (g_fp->_isSaveAllowed && par == 16) { + if (g_fp->_globalMessageQueueList->size() && (*g_fp->_globalMessageQueueList)[0] != 0) { + for (int i = 0; i < g_fp->_globalMessageQueueList->size(); i++) { + if ((*g_fp->_globalMessageQueueList)[i]->_flags & 1) + if ((*g_fp->_globalMessageQueueList)[i] != this && !(*g_fp->_globalMessageQueueList)[i]->_isFinished) + return; + } + } + + if (g_fp->_currentScene) + g_fp->_gameLoader->writeSavegame(g_fp->_currentScene, "savetmp.sav"); + } } void MessageQueue::addExCommand(ExCommand *ex) { diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp index bba5df0cd5..8981cdb8e6 100644 --- a/engines/fullpipe/modal.cpp +++ b/engines/fullpipe/modal.cpp @@ -34,6 +34,8 @@ #include "graphics/palette.h" #include "video/avi_decoder.h" +#include "engines/savestate.h" + namespace Fullpipe { ModalIntro::ModalIntro() { @@ -1084,17 +1086,17 @@ void ModalMainMenu::updateSoundVolume(Sound *snd) { b = 800 - dx; } - int32 pp = b * a; //(0x51EB851F * b * a) >> 32) >> 8; // TODO FIXME + int32 pp = b * a; - snd->setPanAndVolume(pan + (pp >> 31) + pp, par); + snd->setPanAndVolume(pan + pp / 800, par); return; } int dx = _screct.left - ani->_ox; if (dx <= 800) { - int32 s = 0x51EB851F * (800 - dx) * (g_fp->_sfxVolume - (-3500)); // TODO FIXME - int32 p = -3500 + (s >> 31) + (s >> 8); + int32 s = (800 - dx) * (g_fp->_sfxVolume - (-3500)); + int32 p = -3500 + s / 800; if (p > g_fp->_sfxVolume) p = g_fp->_sfxVolume; @@ -1103,8 +1105,6 @@ void ModalMainMenu::updateSoundVolume(Sound *snd) { } else { snd->setPanAndVolume(-3500, 0); } - - warning("STUB: ModalMainMenu::updateSoundVolume()"); } void ModalMainMenu::updateSliderPos() { @@ -1460,6 +1460,8 @@ ModalSaveGame::ModalSaveGame() { _rect = g_fp->_sceneRect; _queryDlg = 0; _mode = 1; + + _objtype = kObjTypeModalSaveGame; } ModalSaveGame::~ModalSaveGame() { @@ -1591,9 +1593,9 @@ void ModalSaveGame::setup(Scene *sc, int mode) { fileinfo = new FileInfo; memset(fileinfo, 0, sizeof(FileInfo)); - snprintf(fileinfo->filename, 160, "save%02d.sav", i); + strncpy(fileinfo->filename, getSavegameFile(i), 160); - if (!getFileInfo(fileinfo->filename, fileinfo)) { + if (!getFileInfo(i, fileinfo)) { fileinfo->empty = true; w = _emptyD->getDimensions(&point)->x; } else { @@ -1623,12 +1625,175 @@ char *ModalSaveGame::getSaveName() { return _files[_queryRes]->filename; } -bool ModalSaveGame::getFileInfo(char *filename, FileInfo *fileinfo) { - warning("STUB: ModalSaveGame::getFileInfo()"); +bool ModalSaveGame::getFileInfo(int slot, FileInfo *fileinfo) { + Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading( + Fullpipe::getSavegameFile(slot)); + + if (!f) + return false; + + Fullpipe::FullpipeSavegameHeader header; + Fullpipe::readSavegameHeader(f, header); + delete f; + + // Create the return descriptor + SaveStateDescriptor desc(slot, header.saveName); + char res[17]; + + snprintf(res, 17, "%s %s", desc.getSaveDate().c_str(), desc.getSaveTime().c_str()); + + for (int i = 0; i < 16; i++) { + switch(res[i]) { + case '.': + fileinfo->date[i] = 11; + break; + case ' ': + fileinfo->date[i] = 12; + break; + case ':': + fileinfo->date[i] = 10; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + fileinfo->date[i] = res[i] - '0'; + break; + default: + error("Incorrect date format: %s", res); + } + } + + return true; +} + +void ModalSaveGame::update() { + if (_menuScene) + _menuScene->draw(); + + _bgr->draw(); + + if (_queryDlg) { + _queryDlg->update(); + + return; + } + + g_fp->_cursorId = PIC_CSR_DEFAULT; + + g_fp->setCursor(g_fp->_cursorId); + + Common::Point point; + + for (uint i = 0; i < _files.size(); i++) { + if (g_fp->_mouseScreenPos.x < _files[i]->fx1 || g_fp->_mouseScreenPos.x > _files[i]->fx2 || + g_fp->_mouseScreenPos.y < _files[i]->fy1 || g_fp->_mouseScreenPos.y > _files[i]->fy2 ) { + if (_files[i]->empty) { + _emptyD->setOXY(_files[i]->fx1, _files[i]->fy1); + _emptyD->draw(); + } else { + int x = _files[i]->fx1; + + for (int j = 0; j < 16; j++) { + _arrayL[_files[i]->date[j]]->setOXY(x + 1, _files[i]->fy1); + _arrayL[_files[i]->date[j]]->draw(); + + x += _arrayL[_files[i]->date[j]]->getDimensions(&point)->x + 2; + } + } + } else { + if (_files[i]->empty) { + _emptyL->setOXY(_files[i]->fx1, _files[i]->fy1); + _emptyL->draw(); + } else { + int x = _files[i]->fx1; + + for (int j = 0; j < 16; j++) { + _arrayD[_files[i]->date[j]]->setOXY(x + 1, _files[i]->fy1); + _arrayD[_files[i]->date[j]]->draw(); + + x += _arrayD[_files[i]->date[j]]->getDimensions(&point)->x + 2; + } + } + } + } + if (_cancelL->isPixelHitAtPos(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y)) + _cancelL->draw(); + else if (_okL->isPixelHitAtPos(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y)) + _okL->draw(); +} + +bool ModalSaveGame::handleMessage(ExCommand *cmd) { + if (_queryDlg) + return _queryDlg->handleMessage(cmd); + + if (cmd->_messageNum == 29) + processMouse(cmd->_x, cmd->_y); + else if (cmd->_messageNum == 36) + processKey(cmd->_keyCode); return false; } +void ModalSaveGame::processMouse(int x, int y) { + for (uint i = 0; i < _files.size(); i++) { + if (x >= _files[i]->fx1 && x <= _files[i]->fx2 && y >= _files[i]->fy1 && y <= _files[i]->fy2) { + _queryRes = i + 1; + + if (_mode) { + if (!_files[i]->empty) { + _queryDlg = new ModalQuery; + + _queryDlg->create(_menuScene, 0, PIC_MOV_BGR); + } + } + + return; + } + } + + if (_cancelL->isPixelHitAtPos(x, y)) + _queryRes = 0; +} + +void ModalSaveGame::saveload() { + if (_objtype != kObjTypeModalSaveGame) + return; + + if (_mode) { + if (getSaveName()) { + bool allowed = true; + + for (Common::Array<MessageQueue *>::iterator s = g_fp->_globalMessageQueueList->begin(); s != g_fp->_globalMessageQueueList->end(); ++s) { + if (!(*s)->_isFinished && ((*s)->getFlags() & 1)) + allowed = false; + } + + if (g_fp->_isSaveAllowed && allowed) + g_fp->_gameLoader->writeSavegame(g_fp->_currentScene, getSaveName()); + } + } else { + if (getSaveName()) { + if (_parentObj) { + delete _parentObj; + + _parentObj = 0; + } + + g_fp->stopAllSoundStreams(); + g_fp->stopSoundStream2(); + + g_fp->_gameLoader->readSavegame(getSaveName()); + } + } +} + void FullpipeEngine::openHelp() { if (!_modalObject) { ModalHelp *help = new ModalHelp; diff --git a/engines/fullpipe/modal.h b/engines/fullpipe/modal.h index a214b1c639..01d8e6b0ee 100644 --- a/engines/fullpipe/modal.h +++ b/engines/fullpipe/modal.h @@ -32,10 +32,7 @@ class Sound; struct FileInfo { char filename[260]; bool empty; - int day; - int month; - int year; - int time; + char date[16]; int fx1; int fx2; int fy1; @@ -46,9 +43,10 @@ class BaseModalObject { public: BaseModalObject *_parentObj; + ObjType _objtype; public: - BaseModalObject() : _parentObj(0) {} + BaseModalObject() : _parentObj(0) { _objtype = kObjTypeDefault; } virtual ~BaseModalObject() {} @@ -256,17 +254,19 @@ public: virtual ~ModalSaveGame(); virtual bool pollEvent() { return true; } - virtual bool handleMessage(ExCommand *message) { return false; } + virtual bool handleMessage(ExCommand *message); virtual bool init(int counterdiff); - virtual void update() {} - virtual void saveload() {} + virtual void update(); + virtual void saveload(); + + void processMouse(int x, int y); void setScene(Scene *sc); void setup(Scene *sc, int mode); void processKey(int key); char *getSaveName(); - bool getFileInfo(char *filename, FileInfo *fileinfo); + bool getFileInfo(int slot, FileInfo *fileinfo); Common::Rect _rect; int _oldBgX; diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp index 35da154570..5b7419c7f4 100644 --- a/engines/fullpipe/motion.cpp +++ b/engines/fullpipe/motion.cpp @@ -125,9 +125,10 @@ void MctlCompound::addObject(StaticANIObject *obj) { } int MctlCompound::removeObject(StaticANIObject *obj) { - warning("STUB: MctlCompound::removeObject()"); + for (uint i = 0; i < _motionControllers.size(); i++) + _motionControllers[i]->_motionControllerObj->removeObject(obj); - return 0; + return 1; } void MctlCompound::initMovGraph2() { @@ -193,7 +194,8 @@ MessageQueue *MctlCompound::method34(StaticANIObject *ani, int sourceX, int sour if (idx == sourceIdx) return _motionControllers[idx]->_motionControllerObj->method34(ani, sourceX, sourceY, fuzzyMatch, staticsId); - MctlConnectionPoint *cp = findClosestConnectionPoint(ani->_ox, ani->_oy, idx, sourceX, sourceY, sourceIdx, &sourceIdx); + double dist; + MctlConnectionPoint *cp = findClosestConnectionPoint(ani->_ox, ani->_oy, idx, sourceX, sourceY, sourceIdx, &dist); if (!cp) return 0; @@ -261,7 +263,8 @@ MessageQueue *MctlCompound::doWalkTo(StaticANIObject *subj, int xpos, int ypos, if (match1 == match2) return _motionControllers[match1]->_motionControllerObj->doWalkTo(subj, xpos, ypos, fuzzyMatch, staticsId); - MctlConnectionPoint *closestP = findClosestConnectionPoint(subj->_ox, subj->_oy, match1, xpos, ypos, match2, &match2); + double dist; + MctlConnectionPoint *closestP = findClosestConnectionPoint(subj->_ox, subj->_oy, match1, xpos, ypos, match2, &dist); if (!closestP) return 0; @@ -427,14 +430,75 @@ MessageQueue *MctlLadder::controllerWalkTo(StaticANIObject *ani, int off) { return doWalkTo(ani, _ladderX + off * _width, _ladderY + off * _height, 1, 0); } -MctlConnectionPoint *MctlCompound::findClosestConnectionPoint(int ox, int oy, int destIndex, int connectionX, int connectionY, int sourceIndex, int *minDistancePtr) { +MctlConnectionPoint *MctlCompound::findClosestConnectionPoint(int ox, int oy, int destIndex, int connectionX, int connectionY, int sourceIndex, double *minDistancePtr) { +#if 0 + if (destIndex == sourceIndex) { + *minDistancePtr = sqrt((double)((oy - connectionY) * (oy - connectionY) + (ox - connectionX) * (ox - connectionX))); + + return 0; + } + + v11 = this->_motionControllers.m_pData; + currDistance = 0.0; + v12 = 0; + v13 = (MctlCompoundArrayItem *)*(&v11->vmt + sourceIndex); + minDistance = 1.0e10; + minConnectionPoint = 0; + if (v13->mctlConnectionPointsArray.CObArray.m_nSize > 0) { + do { + v14 = 0; + for (currMctlIndex = 0; v14 < this->_motionControllers.m_nSize; currMctlIndex = v14) { + v15 = this->_motionControllers.m_pData; + v16 = *(MovGraphReact **)(*(&v15->vmt + v14) + offsetof(MctlCompoundArrayItem, movGraphReactObj)); + if (v16) { + v17 = *(MctlConnectionPoint **)(*(_DWORD *)(*(&v15->vmt + sourceIndex) + 0x10) + 4 * v12);// MctlCompoundArrayItem.mctlConnectionPointsArray.CObArray.m_pData + LOBYTE(v18) = (*(bool (__thiscall **)(MovGraphReact *, int, int))(v16->CObject.vmt + offsetof(MovGraphReactVmt, pointInRegion)))(v16, v17->_connectionX, v17->_connectionY); + if (v18) { + v14 = currMctlIndex; + v19 = *(MctlConnectionPoint **)(*(_DWORD *)(*(&this->_motionControllers.m_pData->vmt + sourceIndex) + 0x10) + 4 * v12); + v20 = MctlCompound_findClosestConnectionPoint(this, ox, oy, destIndex, v19->_connectionX, v19->_connectionY, currMctlIndex, (int *)&currDistance); + if (currDistance < minDistance) { + minDistance = currDistance; + if (v20) + minConnectionPoint = v20; + else + minConnectionPoint = *(MctlConnectionPoint **)(*(_DWORD *)(*(&this->_motionControllers.m_pData->vmt + sourceIndex) + 0x10) + 4 * v12); + } + } else { + v14 = currMctlIndex; + } + } + ++v14; + } + ++v12; + } while (v12 < *(_DWORD *)(*(&this->_motionControllers.m_pData->vmt + sourceIndex) + 0x14)); // MctlCompoundArrayItem.mctlConnectionPointsArray.CObArray.m_nSize + } + + *minDistancePtr = minDistance; + + return minConnectionPoint; +} +#endif warning("STUB: MctlCompound::findClosestConnectionPoint()"); return 0; } void MctlCompound::replaceNodeX(int from, int to) { - warning("STUB: MctlCompound::replaceNodeX()"); + for (uint i = 0; i < _motionControllers.size(); i++) { + if (_motionControllers[i]->_motionControllerObj->_objtype == kObjTypeMovGraph) { + MovGraph *gr = (MovGraph *)_motionControllers[i]->_motionControllerObj; + + for (ObList::iterator n = gr->_nodes.begin(); n != gr->_nodes.end(); ++n) { + MovGraphNode *node = (MovGraphNode *)*n; + + if (node->_x == from) + node->_x = to; + } + + gr->calcNodeDistancesAndAngles(); + } + } } MctlConnectionPoint::MctlConnectionPoint() { @@ -493,15 +557,7 @@ bool MctlCompoundArray::load(MfcArchive &file) { MovGraphItem::MovGraphItem() { ani = 0; field_4 = 0; - field_8 = 0; - field_C = 0; - field_10 = 0; - field_14 = 0; - field_18 = 0; - field_1C = 0; - field_20 = 0; - field_24 = 0; - items = 0; + movitems = 0; count = 0; field_30 = 0; field_34 = 0; @@ -509,16 +565,36 @@ MovGraphItem::MovGraphItem() { field_3C = 0; } +void MovGraphItem::free() { + for (uint i = 0; i < movitems->size(); i++) { + (*movitems)[i]->movarr->_movSteps.clear(); + delete (*movitems)[i]->movarr; + } + + delete movitems; + + movitems = 0; +} + int MovGraph_messageHandler(ExCommand *cmd); -int MovGraphCallback(int a1, int a2, int a3) { - warning("STUB: MovgraphCallback"); +MovArr *movGraphCallback(StaticANIObject *ani, Common::Array<MovItem *> *items, signed int counter) { + int residx = 0; + int itemidx = 0; - return 0; + while (counter > 1) { + if ((*items)[itemidx]->_mfield_4 > (*items)[itemidx + 1]->_mfield_4) + residx = itemidx; + + counter--; + itemidx++; + } + + return (*items)[residx]->movarr; } MovGraph::MovGraph() { - _callback1 = MovGraphCallback; + _callback1 = movGraphCallback; _field_44 = 0; insertMessageHandler(MovGraph_messageHandler, getMessageHandlersCount() - 1, 129); @@ -562,54 +638,482 @@ int MovGraph::removeObject(StaticANIObject *obj) { } void MovGraph::freeItems() { - warning("STUB: MovGraph::freeItems()"); + for (uint i = 0; i < _items.size(); i++) { + _items[i]->free(); + + _items[i]->movarr._movSteps.clear(); + } + + _items.clear(); } +Common::Array<MovItem *> *MovGraph::method28(StaticANIObject *ani, int x, int y, int flag1, int *rescount) { + *rescount = 0; + + if (_items.size() <= 0) + return 0; + + int idx = 0; -int MovGraph::method28() { - warning("STUB: MovGraph::method28()"); + while (_items[idx]->ani != ani) { + idx++; + + if (idx >= _items.size()) + return 0; + } + _items[idx]->free(); + + calcNodeDistancesAndAngles(); + + _items[idx]->movarr._movSteps.clear(); + + Common::Point point; + + point.x = ani->_ox; + point.y = ani->_oy; + + if (!calcChunk(idx, ani->_ox, ani->_oy, &_items[idx]->movarr, 0)) + findClosestLink(idx, &point, &_items[idx]->movarr); + + _items[idx]->count = 0; + + delete _items[idx]->movitems; + _items[idx]->movitems = 0; + + int arrSize; + Common::Array<MovArr *> *movarr = genMovArr(x, y, &arrSize, flag1, 0); + + if (movarr) { + for (int i = 0; i < arrSize; i++) { + int sz; + Common::Array<MovItem *> *movitems = calcMovItems(&_items[idx]->movarr, (*movarr)[i], &sz); + + if (sz > 0) { + for (uint j = 0; j < sz; j++) + _items[idx]->movitems->push_back(movitems[j]); + + delete movitems; + } + } + + delete movarr; + } + + if (_items[idx]->count) { + *rescount = _items[idx]->count; + + return _items[idx]->movitems; + } return 0; } -int MovGraph::method2C(StaticANIObject *obj, int x, int y) { +bool MovGraph::method2C(StaticANIObject *obj, int x, int y) { obj->setOXY(x, y); return method3C(obj, 1); } -MessageQueue *MovGraph::method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) { - warning("STUB: MovGraph::method34()"); +MessageQueue *MovGraph::method34(StaticANIObject *ani, int xpos, int ypos, int fuzzyMatch, int staticsId) { + if (!ani) { + if (!_items.size()) + return 0; - return 0; -} + ani = _items[0]->ani; + } + + if (ABS(ani->_ox - xpos) < 50 && ABS(ani->_oy - ypos) < 50) + return 0; -int MovGraph::changeCallback() { - warning("STUB: MovGraph::changeCallback()"); + if (!ani->isIdle()) + return 0; - return 0; + if (ani->_flags & 0x100) + return 0; + + int count; + Common::Array<MovItem *> *movitems = method28(ani, xpos, ypos, fuzzyMatch, &count); + + if (!movitems) + return 0; + + if (ani->_movement) { + Common::Point point; + + ani->calcStepLen(&point); + + MessageQueue *mq = sub1(ani, ani->_ox - point.x, ani->_oy - point.y, ani->_movement->_staticsObj1->_staticsId, xpos, ypos, 0, fuzzyMatch); + + if (!mq || !mq->getExCommandByIndex(0)) + return 0; + + ExCommand *ex = mq->getExCommandByIndex(0); + + if ((ex->_messageKind != 1 && ex->_messageKind != 20) || ex->_messageNum != ani->_movement->_id || + (ex->_field_14 >= 1 && ex->_field_14 <= ani->_movement->_currDynamicPhaseIndex)) { + mq = new MessageQueue(g_fp->_globalMessageQueueList->compact()); + + ex = new ExCommand(ani->_id, 21, 0, 0, 0, 0, 1, 0, 0, 0); + ex->_keyCode = ani->_okeyCode; + ex->_field_3C = 1; + ex->_field_24 = 0; + mq->addExCommandToEnd(ex); + + ex = new ExCommand(ani->_id, 51, 0, xpos, ypos, 0, 1, 0, 0, 0); + ex->_keyCode = ani->_okeyCode; + ex->_field_3C = 1; + ex->_field_24 = 0; + ex->_field_20 = fuzzyMatch; + mq->addExCommandToEnd(ex); + + if (mq->chain(0)) + return mq; + + delete mq; + + return 0; + } + + int count2; + + ani->setSomeDynamicPhaseIndex(ex->_field_14); + method28(ani, xpos, ypos, fuzzyMatch, &count2); + + int idx = getItemIndexByStaticAni(ani); + count = _items[idx]->count; + movitems = _items[idx]->movitems; + } + + return method50(ani, _callback1(ani, movitems, count), staticsId); } -int MovGraph::method3C(StaticANIObject *ani, int flag) { - warning("STUB: MovGraph::method3C()"); +void MovGraph::changeCallback(MovArr *(*callback1)(StaticANIObject *ani, Common::Array<MovItem *> *items, signed int counter)) { + _callback1 = callback1; +} - return 0; +bool MovGraph::method3C(StaticANIObject *ani, int flag) { + int idx = getItemIndexByStaticAni(ani); + + if (idx == -1) + return false; + + Common::Point point; + MovArr movarr; + + point.x = ani->_ox; + point.y = ani->_oy; + + findClosestLink(idx, &point, &movarr); + ani->setOXY(point.x, point.y); + + if (flag) { + Statics *st; + + if (ani->_statics) { + int t = _mgm.refreshOffsets(ani->_id, ani->_statics->_staticsId, movarr._link->_dwordArray2[_field_44]); + if (t > _mgm.refreshOffsets(ani->_id, ani->_statics->_staticsId, movarr._link->_dwordArray2[_field_44 + 1])) + st = ani->getStaticsById(movarr._link->_dwordArray2[_field_44 + 1]); + else + st = ani->getStaticsById(movarr._link->_dwordArray2[_field_44]); + } else { + ani->stopAnim_maybe(); + st = ani->getStaticsById(movarr._link->_dwordArray2[_field_44]); + } + + ani->_statics = st; + } + + return true; } -int MovGraph::method44() { - warning("STUB: MovGraph::method44()"); +bool MovGraph::method44(StaticANIObject *ani, int x, int y) { + int idx = getItemIndexByStaticAni(ani); + MovArr m; - return 0; + if (idx != -1) { + if (x != -1 || y != -1) { + int counter; + + Common::Array<MovItem *> *movitem = method28(ani, x, y, 0, &counter); + + if (movitem) { + MovArr *movarr = _callback1(ani, movitem, counter); + int cnt = movarr->_movStepCount; + + if (cnt > 0) { + if (movarr->_movSteps[cnt - 1]->link->_flags & 0x4000000) + return true; + } + } + } else if (calcChunk(idx, ani->_ox, ani->_oy, &m, 0) && m._link && (m._link->_flags & 0x4000000)) { + return true; + } + } + + return false; } MessageQueue *MovGraph::doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) { - warning("STUB: MovGraph::doWalkTo()"); + PicAniInfo picAniInfo; + int ss; + + Common::Array<MovItem *> *movitem = method28(subj, xpos, ypos, fuzzyMatch, &ss); + + subj->getPicAniInfo(&picAniInfo); + + if (movitem) { + MovArr *goal = _callback1(subj, movitem, ss); + int idx = getItemIndexByStaticAni(subj); + + for (int i = 0; i < _items[idx]->count; i++) { + if ((*_items[idx]->movitems)[i]->movarr == goal) { + if (subj->_movement) { + Common::Point point; + + subj->calcStepLen(&point); + + MessageQueue *mq = sub1(subj, subj->_ox - point.x, subj->_oy - point.y, subj->_movement->_staticsObj1->_staticsId, xpos, ypos, 0, fuzzyMatch); + + if (!mq || !mq->getExCommandByIndex(0)) + return 0; + + ExCommand *ex = mq->getExCommandByIndex(0); + + if ((ex->_messageKind != 1 && ex->_messageKind != 20) || + ex->_messageNum != subj->_movement->_id || + (ex->_field_14 >= 1 && ex->_field_14 <= subj->_movement->_currDynamicPhaseIndex)) + subj->playIdle(); + } + } + } + } + + movitem = method28(subj, xpos, ypos, fuzzyMatch, &ss); + if (movitem) { + MovArr *goal = _callback1(subj, movitem, ss); + int idx = getItemIndexByStaticAni(subj); + + if (_items[idx]->count > 0) { + int arridx = 0; + + while ((*_items[idx]->movitems)[arridx]->movarr != goal) { + arridx++; + + if (arridx >= _items[idx]->count) { + subj->setPicAniInfo(&picAniInfo); + return 0; + } + } + + _items[idx]->movarr._movSteps.clear(); + _items[idx]->movarr = *(*_items[idx]->movitems)[arridx]->movarr; + _items[idx]->movarr._movSteps = (*_items[idx]->movitems)[arridx]->movarr->_movSteps; + _items[idx]->movarr._afield_8 = -1; + _items[idx]->movarr._link = 0; + + MessageQueue *mq = fillMGMinfo(_items[idx]->ani, &_items[idx]->movarr, staticsId); + if (mq) { + ExCommand *ex = new ExCommand(); + ex->_messageKind = 17; + ex->_messageNum = 54; + ex->_parentId = subj->_id; + ex->_field_3C = 1; + mq->addExCommandToEnd(ex); + } + subj->setPicAniInfo(&picAniInfo); + + return mq; + } + } + + subj->setPicAniInfo(&picAniInfo); return 0; } -int MovGraph::method50() { - warning("STUB: MovGraph::method50()"); +MessageQueue *MovGraph::sub1(StaticANIObject *ani, int x, int y, int stid, int x1, int y1, int stid2, int flag1) { + PicAniInfo picinfo; - return 0; + ani->getPicAniInfo(&picinfo); + + ani->_statics = ani->getStaticsById(stid); + ani->_movement = 0; + ani->setOXY(x, y); + + int rescount; + + Common::Array<MovItem *> *movitems = method28(ani, x1, y1, flag1, &rescount); + + if (!movitems) { + ani->setPicAniInfo(&picinfo); + + return 0; + } + + MessageQueue *res = 0; + + MovArr *goal = _callback1(ani, movitems, rescount); + int idx = getItemIndexByStaticAni(ani); + + MovGraphItem *movgitem = _items[idx]; + int cnt = movgitem->count; + + for (int nidx = 0; nidx < cnt; nidx++) { + if ((*movgitem->movitems)[nidx]->movarr == goal) { + movgitem->movarr._movSteps.clear(); + _items[idx]->movarr = *(*movgitem->movitems)[nidx]->movarr; + _items[idx]->movarr._movSteps = (*movgitem->movitems)[nidx]->movarr->_movSteps; + _items[idx]->movarr._afield_8 = -1; + _items[idx]->movarr._link = 0; + + res = fillMGMinfo(_items[idx]->ani, &_items[idx]->movarr, stid2); + } + } + + ani->setPicAniInfo(&picinfo); + + return res; +} + +MessageQueue *MovGraph::fillMGMinfo(StaticANIObject *ani, MovArr *movarr, int staticsId) { + if (!movarr->_movStepCount) + return 0; + + MessageQueue *mq = 0; + int ox = ani->_ox; + int oy = ani->_oy; + int id1 = 0; + int id2; + + for (int i = 0; i < movarr->_movStepCount; i++) { + while (i < movarr->_movStepCount - 1) { + if (movarr->_movSteps[i ]->link->_dwordArray1[movarr->_movSteps[i - 1]->sfield_0 + _field_44] != + movarr->_movSteps[i + 1]->link->_dwordArray1[movarr->_movSteps[i ]->sfield_0 + _field_44]) + break; + i++; + } + + MovStep *st = movarr->_movSteps[i]; + + ani->getMovementById(st->link->_dwordArray1[_field_44 + st->sfield_0]); + + if (i == movarr->_movStepCount - 1 && staticsId) { + id2 = staticsId; + } else { + if (i < movarr->_movStepCount - 1) + id2 = ani->getMovementById(movarr->_movSteps[i + 1]->link->_dwordArray1[_field_44 + st->sfield_0])->_staticsObj1->_staticsId; + else + id2 = st->link->_dwordArray2[_field_44 + st->sfield_0]; + } + + int nx, ny, nd; + + if (i == movarr->_movStepCount - 1) { + nx = movarr->_point.x; + ny = movarr->_point.y; + nd = st->link->_movGraphNode1->_distance; + } else { + if (st->sfield_0) { + nx = st->link->_movGraphNode1->_x; + ny = st->link->_movGraphNode1->_y; + nd = st->link->_movGraphNode1->_distance; + } else { + nx = st->link->_movGraphNode2->_x; + ny = st->link->_movGraphNode2->_y; + nd = st->link->_movGraphNode2->_distance; + } + } + + MGMInfo mgminfo; + + memset(&mgminfo, 0, sizeof(mgminfo)); + mgminfo.ani = ani; + mgminfo.staticsId2 = id2; + mgminfo.staticsId1 = id1; + mgminfo.x1 = nx; + mgminfo.x2 = ox; + mgminfo.y2 = oy; + mgminfo.y1 = ny; + mgminfo.field_1C = nd; + mgminfo.movementId = st->link->_dwordArray1[_field_44 + st->sfield_0]; + + mgminfo.flags = 0xe; + if (mq) + mgminfo.flags |= 0x31; + + MessageQueue *newmq = _mgm.genMovement(&mgminfo); + + if (mq) { + if (newmq) { + mq->transferExCommands(newmq); + + delete newmq; + } + } else { + mq = newmq; + } + + ox = nx; + oy = ny; + id1 = id2; + } + + return mq; +} + +MessageQueue *MovGraph::method50(StaticANIObject *ani, MovArr *movarr, int staticsId) { + if (_items.size() == 0) + return 0; + + uint idx; + int movidx; + bool done = false; + + for (idx = 0; idx <= _items.size() && !done; idx++) { + if (idx == _items.size()) + return 0; + + if (_items[idx]->ani == ani) { + if (!_items[idx]->movitems) + return 0; + + if (_items[idx]->count < 1) + return 0; + + for (movidx = 0; movidx < _items[idx]->count; movidx++) { + if ((*_items[idx]->movitems)[movidx]->movarr == movarr) { + done = true; + + break; + } + } + } + } + + _items[idx]->movarr._movSteps.clear(); + _items[idx]->movarr = *(*_items[idx]->movitems)[movidx]->movarr; + _items[idx]->movarr._movSteps = (*_items[idx]->movitems)[movidx]->movarr->_movSteps; + _items[idx]->movarr._afield_8 = -1; + _items[idx]->movarr._link = 0; + + MessageQueue *mq = fillMGMinfo(_items[idx]->ani, &_items[idx]->movarr, 0); + + if (!mq) + return 0; + + ExCommand *ex = new ExCommand(); + + ex->_messageKind = 17; + ex->_messageNum = 54; + ex->_parentId = ani->_id; + ex->_field_3C = 1; + mq->addExCommandToEnd(ex); + + if (!mq->chain(ani)) { + delete mq; + + return 0; + } + + return mq; } double MovGraph::calcDistance(Common::Point *point, MovGraphLink *link, int fuzzyMatch) { @@ -660,6 +1164,61 @@ void MovGraph::calcNodeDistancesAndAngles() { } } +bool MovGraph::findClosestLink(int unusedArg, Common::Point *p, MovArr *movarr) { + MovGraphLink *link = 0; + double mindist = 1.0e20; + int resx = 0, resy = 0; + + for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) { + MovGraphLink *lnk = (MovGraphLink *)*i; + + if ((lnk->_flags & 0x10000000) && !(lnk->_flags & 0x20000000) ) { + double dx1 = lnk->_movGraphNode1->_x - p->x; + double dy1 = lnk->_movGraphNode1->_y - p->y; + double dx2 = lnk->_movGraphNode2->_x - p->x; + double dy2 = lnk->_movGraphNode2->_y - p->y; + double dx3 = lnk->_movGraphNode2->_x - lnk->_movGraphNode1->_x; + double dy3 = lnk->_movGraphNode2->_y - lnk->_movGraphNode1->_y; + double sq1 = sqrt(dy1 * dy1 + dx1 * dx1); + double sdist = (dy3 * dy1 + dx3 * dx1) / lnk->_distance / sq1; + double ldist = sdist * sq1; + double dist = sqrt(1.0 - sdist * sdist) * sq1; + + if (ldist < 0.0) { + ldist = 0.0; + dist = sqrt(dx1 * dx1 + dy1 * dy1); + } + + if (ldist > lnk->_distance) { + ldist = lnk->_distance; + dist = sqrt(dx2 * dx2 + dy2 * dy2); + } + + if (ldist >= 0.0 && ldist <= lnk->_distance && dist < mindist) { + resx = lnk->_movGraphNode1->_x + (int)(dx3 * ldist / lnk->_distance); + resy = lnk->_movGraphNode1->_y + (int)(dy3 * ldist / lnk->_distance); + + mindist = dist; + link = lnk; + } + } + } + + if (mindist < 1.0e20) { + if (movarr) + movarr->_link = link; + + if (p) { + p->x = resx; + p->y = resy; + } + + return true; + } + + return false; +} + int MovGraph::getItemIndexByStaticAni(StaticANIObject *ani) { for (uint i = 0; i < _items.size(); i++) if (_items[i]->ani == ani) @@ -668,6 +1227,209 @@ int MovGraph::getItemIndexByStaticAni(StaticANIObject *ani) { return -1; } +Common::Array<MovArr *> *MovGraph::genMovArr(int x, int y, int *arrSize, int flag1, int flag2) { + if (!_links.size()) { + *arrSize = 0; + + return 0; + } + + Common::Array<MovArr *> *arr = new Common::Array<MovArr *>; + MovArr *movarr; + + for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) { + MovGraphLink *lnk = (MovGraphLink *)*i; + + if (flag1) { + Common::Point point(x, y); + double dist = calcDistance(&point, lnk, 0); + + if (dist >= 0.0 && dist < 2.0) { + movarr = new MovArr; + + movarr->_link = lnk; + movarr->_dist = ((double)(lnk->_movGraphNode1->_y - lnk->_movGraphNode2->_y) * (double)(lnk->_movGraphNode1->_y - point.y) + + (double)(lnk->_movGraphNode2->_x - lnk->_movGraphNode1->_x) * (double)(point.x - lnk->_movGraphNode1->_x)) / + lnk->_distance / lnk->_distance; + movarr->_point = point; + + arr->push_back(movarr); + } + } else { + if (lnk->_movGraphReact) { + if (lnk->_movGraphReact->pointInRegion(x, y)) { + if (!(lnk->_flags & 0x10000000) || lnk->_flags & 0x20000000) { + if (!flag2) { + movarr = new MovArr; + movarr->_link = lnk; + movarr->_dist = 0.0; + movarr->_point.x = lnk->_movGraphNode1->_x; + movarr->_point.y = lnk->_movGraphNode1->_y; + arr->push_back(movarr); + + movarr = new MovArr; + movarr->_link = lnk; + movarr->_dist = 1.0; + movarr->_point.x = lnk->_movGraphNode1->_x; + movarr->_point.y = lnk->_movGraphNode1->_y; + arr->push_back(movarr); + } + } else { + movarr = new MovArr; + movarr->_link = lnk; + movarr->_dist = ((double)(lnk->_movGraphNode1->_y - lnk->_movGraphNode2->_y) * (double)(lnk->_movGraphNode1->_y - y) + + (double)(lnk->_movGraphNode2->_x - lnk->_movGraphNode1->_x) * (double)(x - lnk->_movGraphNode1->_x)) / + lnk->_distance / lnk->_distance; + movarr->_point.x = x; + movarr->_point.y = y; + + calcDistance(&movarr->_point, lnk, 0); + + arr->push_back(movarr); + } + } + } + } + } + + *arrSize = arr->size(); + + return arr; +} + +void MovGraph::shuffleTree(MovGraphLink *lnk, MovGraphLink *lnk2, Common::Array<MovGraphLink *> &tempObList1, Common::Array<MovGraphLink *> &tempObList2) { + if (lnk == lnk2) { + for (uint i = 0; i < tempObList1.size(); i++) + tempObList2.push_back(tempObList1[i]); + + tempObList2.push_back(lnk); + } else { + lnk->_flags |= 0x80000000; + + tempObList1.push_back(lnk); + + for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) { + MovGraphLink *l = (MovGraphLink *)*i; + + if (l->_movGraphNode1 != lnk->_movGraphNode1) { + if (l->_movGraphNode2 != lnk->_movGraphNode1) { + if (l->_movGraphNode1 != lnk->_movGraphNode2 && l->_movGraphNode2 != lnk->_movGraphNode2) + continue; + } + } + + if (!(l->_flags & 0xA0000000)) + shuffleTree(l, lnk2, tempObList1, tempObList2); + } + + lnk->_flags &= 0x7FFFFFFF; + } +} + +Common::Array<MovItem *> *MovGraph::calcMovItems(MovArr *movarr1, MovArr *movarr2, int *listCount) { + Common::Array<MovGraphLink *> tempObList1; + Common::Array<MovGraphLink *> tempObList2; + + shuffleTree(movarr1->_link, movarr2->_link, tempObList1, tempObList2); + + *listCount = 0; + + if (!tempObList2.size()) + return 0; + + *listCount = tempObList2.size(); + + Common::Array<MovItem *> *res = new Common::Array<MovItem *>; + + for (int i = 0; i < *listCount; i++) { + MovItem *r = new MovItem; + + genMovItem(r, tempObList2[i], movarr1, movarr2); + + delete tempObList2[i]; + } + + movarr2->_link = movarr1->_link; + + return res; +} + +void MovGraph::genMovItem(MovItem *movitem, MovGraphLink *grlink, MovArr *movarr1, MovArr *movarr2) { + warning("STUB: MovGraph::genMovItem()"); +} + +bool MovGraph::calcChunk(int idx, int x, int y, MovArr *arr, int a6) { + int staticsId; + + if (_items[idx]->ani->_statics) { + staticsId = _items[idx]->ani->_statics->_staticsId; + } else { + if (!_items[idx]->ani->_movement->_staticsObj2) + return 0; + + staticsId = _items[idx]->ani->_movement->_staticsObj2->_staticsId; + } + + int arrSize; + + Common::Array<MovArr *> *movarr = genMovArr(x, y, &arrSize, 0, 1); + + if (!movarr) + return findClosestLink(idx, 0, arr); + + bool res = false; + + int idxmin = -1; + int offmin = 100; + + for (int i = 0; i < arrSize; i++) { + int off = _mgm.refreshOffsets(_items[idx]->ani->_id, staticsId, (*movarr)[i]->_link->_dwordArray2[_field_44]); + + if (off < offmin) { + offmin = off; + idxmin = i; + } + + off = _mgm.refreshOffsets(_items[idx]->ani->_id, staticsId, (*movarr)[i]->_link->_dwordArray2[_field_44 + 1]); + if (off < offmin) { + offmin = off; + idxmin = i; + } + } + + if (idxmin != -1) { + *arr = *(*movarr)[idxmin]; + + res = true; + } + + delete movarr; + + return res; +} + +void MovGraph::setEnds(MovStep *step1, MovStep *step2) { + if (step1->link->_movGraphNode1 == step2->link->_movGraphNode2) { + step1->sfield_0 = 1; + step2->sfield_0 = 1; + + return; + } + + if (step1->link->_movGraphNode1 == step2->link->_movGraphNode1) { + step1->sfield_0 = 1; + step2->sfield_0 = 0; + } else { + step1->sfield_0 = 0; + + if (step1->link->_movGraphNode2 != step2->link->_movGraphNode1) { + step2->sfield_0 = 1; + } else { + step2->sfield_0 = 0; + } + } +} + int MovGraph2::getItemIndexByGameObjectId(int objectId) { for (uint i = 0; i < _items2.size(); i++) if (_items2[i]->_objectId == objectId) @@ -1089,7 +1851,10 @@ int MovGraph2::removeObject(StaticANIObject *obj) { } void MovGraph2::freeItems() { - warning("STUB: MovGraph2::freeItems()"); + for (uint i = 0; i < _items2.size(); i++) + delete _items2[i]; + + _items2.clear(); } MessageQueue *MovGraph2::method34(StaticANIObject *ani, int xpos, int ypos, int fuzzyMatch, int staticsId) { @@ -1140,6 +1905,8 @@ MessageQueue *MovGraph2::doWalkTo(StaticANIObject *obj, int xpos, int ypos, int PicAniInfo picAniInfo; Common::Point point; + debug(0, "MovGraph2::doWalkTo(%d, %d, %d, %d, %d)", obj->_id, xpos, ypos, fuzzyMatch, staticsId); + int idx = getItemIndexByGameObjectId(obj->_id); if (idx < 0) @@ -2528,7 +3295,10 @@ MovGraphLink::MovGraphLink() { } MovGraphLink::~MovGraphLink() { - warning("STUB: MovGraphLink::~MovGraphLink()"); + delete _movGraphReact; + + _dwordArray1.clear(); + _dwordArray2.clear(); } @@ -2764,26 +3534,26 @@ bool MovGraphReact::pointInRegion(int x, int y) { } } -int startWalkTo(int objId, int objKey, int x, int y, int a5) { - MctlCompound *mc = getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId); +int startWalkTo(int objId, int objKey, int x, int y, int fuzzyMatch) { + MctlCompound *mc = getCurrSceneSc2MotionController(); if (mc) - return (mc->method34(g_fp->_currentScene->getStaticANIObject1ById(objId, objKey), x, y, a5, 0) != 0); + return (mc->method34(g_fp->_currentScene->getStaticANIObject1ById(objId, objKey), x, y, fuzzyMatch, 0) != 0); return 0; } -int doSomeAnimation(int objId, int objKey, int a3) { +bool doSomeAnimation(int objId, int objKey, int a3) { StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(objId, objKey); MctlCompound *cmp = getCurrSceneSc2MotionController(); if (ani && cmp) return cmp->method3C(ani, a3); - return 0; + return false; } -int doSomeAnimation2(int objId, int objKey) { +bool doSomeAnimation2(int objId, int objKey) { return doSomeAnimation(objId, objKey, 0); } diff --git a/engines/fullpipe/motion.h b/engines/fullpipe/motion.h index 4d92fd7fed..2b40791340 100644 --- a/engines/fullpipe/motion.h +++ b/engines/fullpipe/motion.h @@ -31,10 +31,12 @@ class MctlConnectionPoint; class MovGraphLink; class MessageQueue; class ExCommand2; +struct MovArr; +struct MovItem; int startWalkTo(int objId, int objKey, int x, int y, int a5); -int doSomeAnimation(int objId, int objKey, int a3); -int doSomeAnimation2(int objId, int objKey); +bool doSomeAnimation(int objId, int objKey, int a3); +bool doSomeAnimation2(int objId, int objKey); class MotionController : public CObject { public: @@ -52,14 +54,14 @@ public: virtual void addObject(StaticANIObject *obj) {} virtual int removeObject(StaticANIObject *obj) { return 0; } virtual void freeItems() {} - virtual int method28() { return 0; } - virtual int method2C(StaticANIObject *obj, int x, int y) { return 0; } + virtual Common::Array<MovItem *> *method28(StaticANIObject *ani, int x, int y, int flag1, int *rescount) { return 0; } + virtual bool method2C(StaticANIObject *obj, int x, int y) { return false; } virtual int method30() { return 0; } virtual MessageQueue *method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) { return 0; } - virtual int changeCallback() { return 0; } - virtual int method3C(StaticANIObject *ani, int flag) { return 0; } + virtual void changeCallback(MovArr *(*_callback1)(StaticANIObject *ani, Common::Array<MovItem *> *items, signed int counter)) {} + virtual bool method3C(StaticANIObject *ani, int flag) { return 0; } virtual int method40() { return 0; } - virtual int method44() { return 0; } + virtual bool method44(StaticANIObject *ani, int x, int y) { return false; } virtual int method48() { return -1; } virtual MessageQueue *doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) { return 0; } @@ -115,7 +117,7 @@ public: virtual MessageQueue *doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId); void initMovGraph2(); - MctlConnectionPoint *findClosestConnectionPoint(int ox, int oy, int destIndex, int connectionX, int connectionY, int sourceIndex, int *minDistancePtr); + MctlConnectionPoint *findClosestConnectionPoint(int ox, int oy, int destIndex, int connectionX, int connectionY, int sourceIndex, double *minDistancePtr); void replaceNodeX(int from, int to); uint getMotionControllerCount() { return _motionControllers.size(); } @@ -299,18 +301,32 @@ class MovGraphLink : public CObject { void calcNodeDistanceAndAngle(); }; +struct MovStep { + int sfield_0; + MovGraphLink *link; +}; + +struct MovArr { + Common::Array<MovStep *> _movSteps; + int _movStepCount; + int _afield_8; + MovGraphLink *_link; + double _dist; + Common::Point _point; +}; + +struct MovItem { + MovArr *movarr; + int _mfield_4; + int _mfield_8; + int _mfield_C; +}; + struct MovGraphItem { StaticANIObject *ani; int field_4; - int field_8; - int field_C; - int field_10; - int field_14; - int field_18; - int field_1C; - int field_20; - int field_24; - int items; + MovArr movarr; + Common::Array<MovItem *> *movitems; int count; int field_30; int field_34; @@ -318,6 +334,7 @@ struct MovGraphItem { int field_3C; MovGraphItem(); + void free(); }; class MovGraph : public MotionController { @@ -326,7 +343,7 @@ public: ObList _links; int _field_44; Common::Array<MovGraphItem *> _items; - int (*_callback1)(int, int, int); + MovArr *(*_callback1)(StaticANIObject *ani, Common::Array<MovItem *> *items, signed int counter); MGM _mgm; public: @@ -338,19 +355,28 @@ public: virtual void addObject(StaticANIObject *obj); virtual int removeObject(StaticANIObject *obj); virtual void freeItems(); - virtual int method28(); - virtual int method2C(StaticANIObject *obj, int x, int y); + virtual Common::Array<MovItem *> *method28(StaticANIObject *ani, int x, int y, int flag1, int *rescount); + virtual bool method2C(StaticANIObject *obj, int x, int y); virtual MessageQueue *method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId); - virtual int changeCallback(); - virtual int method3C(StaticANIObject *ani, int flag); - virtual int method44(); + virtual void changeCallback(MovArr *(*_callback1)(StaticANIObject *ani, Common::Array<MovItem *> *items, signed int counter)); + virtual bool method3C(StaticANIObject *ani, int flag); + virtual bool method44(StaticANIObject *ani, int x, int y); virtual MessageQueue *doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId); - virtual int method50(); + virtual MessageQueue *method50(StaticANIObject *ani, MovArr *movarr, int staticsId); double calcDistance(Common::Point *point, MovGraphLink *link, int fuzzyMatch); void calcNodeDistancesAndAngles(); + bool findClosestLink(int unusedArg, Common::Point *p, MovArr *movarr); MovGraphNode *calcOffset(int ox, int oy); int getItemIndexByStaticAni(StaticANIObject *ani); + Common::Array<MovArr *> *genMovArr(int x, int y, int *arrSize, int flag1, int flag2); + void shuffleTree(MovGraphLink *lnk, MovGraphLink *lnk2, Common::Array<MovGraphLink *> &tempObList1, Common::Array<MovGraphLink *> &tempObList2); + Common::Array<MovItem *> *calcMovItems(MovArr *movarr1, MovArr *movarr2, int *listCount); + void genMovItem(MovItem *movitem, MovGraphLink *grlink, MovArr *movarr1, MovArr *movarr2); + bool calcChunk(int idx, int x, int y, MovArr *arr, int a6); + MessageQueue *sub1(StaticANIObject *ani, int x, int y, int a5, int x1, int y1, int a8, int a9); + MessageQueue *fillMGMinfo(StaticANIObject *ani, MovArr *movarr, int staticsId); + void setEnds(MovStep *step1, MovStep *step2); }; class Movement; diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp index 462401b3b2..1247d9380e 100644 --- a/engines/fullpipe/scene.cpp +++ b/engines/fullpipe/scene.cpp @@ -133,7 +133,27 @@ Scene::Scene() { } Scene::~Scene() { - warning("STUB: Scene::~Scene()"); + delete _soundList; + delete _shadows; + delete _palette; + + // _faObjlist is not used + + for (uint i = 0; i < _messageQueueList.size(); i++) + delete _messageQueueList[i]; + + _messageQueueList.clear(); + + for (uint i = 0; i < _staticANIObjectList1.size(); i++) + delete _staticANIObjectList1[i]; + + _staticANIObjectList1.clear(); + + delete _libHandle; + + // delete _field_BC; + + free(_sceneName); } bool Scene::load(MfcArchive &file) { @@ -249,7 +269,7 @@ bool Scene::load(MfcArchive &file) { void Scene::initStaticANIObjects() { for (uint i = 0; i < _staticANIObjectList1.size(); i++) - ((StaticANIObject *)_staticANIObjectList1[i])->initMovements(); + _staticANIObjectList1[i]->initMovements(); } void Scene::init() { @@ -262,13 +282,13 @@ void Scene::init() { ((PictureObject *)_picObjList[i])->clearFlags(); for (uint i = 0; i < _staticANIObjectList1.size(); i++) - ((StaticANIObject *)_staticANIObjectList1[i])->clearFlags(); + _staticANIObjectList1[i]->clearFlags(); if (_staticANIObjectList2.size() != _staticANIObjectList1.size()) { _staticANIObjectList2.clear(); - for (PtrList::iterator s = _staticANIObjectList1.begin(); s != _staticANIObjectList1.end(); ++s) - _staticANIObjectList2.push_back(*s); + for (uint i = 0; i < _staticANIObjectList1.size(); i++) + _staticANIObjectList2.push_back(_staticANIObjectList1[i]); } } @@ -281,35 +301,33 @@ StaticANIObject *Scene::getAniMan() { } StaticANIObject *Scene::getStaticANIObject1ById(int obj, int a3) { - for (PtrList::iterator s = _staticANIObjectList1.begin(); s != _staticANIObjectList1.end(); ++s) { - StaticANIObject *o = (StaticANIObject *)*s; - if (o->_id == obj && (a3 == -1 || o->_okeyCode == a3)) - return o; + for (uint i = 0; i < _staticANIObjectList1.size(); i++) { + if (_staticANIObjectList1[i]->_id == obj && (a3 == -1 || _staticANIObjectList1[i]->_okeyCode == a3)) + return _staticANIObjectList1[i]; } return 0; } StaticANIObject *Scene::getStaticANIObject1ByName(char *name, int a3) { - for (uint n = 0; n < _staticANIObjectList1.size(); n++) { - StaticANIObject *o = (StaticANIObject *)_staticANIObjectList1[n]; - if (!strcmp(o->_objectName, name) && (a3 == -1 || o->_okeyCode == a3)) - return o; + for (uint i = 0; i < _staticANIObjectList1.size(); i++) { + if (!strcmp(_staticANIObjectList1[i]->_objectName, name) && (a3 == -1 || _staticANIObjectList1[i]->_okeyCode == a3)) + return _staticANIObjectList1[i]; } return 0; } void Scene::deleteStaticANIObject(StaticANIObject *obj) { - for (uint n = 0; n < _staticANIObjectList1.size(); n++) - if ((StaticANIObject *)_staticANIObjectList1[n] == obj) { - _staticANIObjectList1.remove_at(n); + for (uint i = 0; i < _staticANIObjectList1.size(); i++) + if (_staticANIObjectList1[i] == obj) { + _staticANIObjectList1.remove_at(i); break; } - for (uint n = 0; n < _staticANIObjectList2.size(); n++) - if ((StaticANIObject *)_staticANIObjectList2[n] == obj) { - _staticANIObjectList2.remove_at(n); + for (uint i = 0; i < _staticANIObjectList2.size(); i++) + if (_staticANIObjectList2[i] == obj) { + _staticANIObjectList2.remove_at(i); break; } } @@ -335,11 +353,12 @@ void Scene::setPictureObjectsFlag4() { } void Scene::stopAllSounds() { - warning("STUB: Scene:stopAllSounds()"); + for (int i = 0; i < _soundList->getCount(); i++) + _soundList->getSoundByIndex(i)->stop(); } PictureObject *Scene::getPictureObjectById(int objId, int flags) { - for (uint i = 0; i < _picObjList.size(); i++) { + for (uint i = 1; i < _picObjList.size(); i++) { if (((PictureObject *)_picObjList[i])->_id == objId && ((PictureObject *)_picObjList[i])->_okeyCode == flags) return (PictureObject *)_picObjList[i]; } @@ -369,16 +388,16 @@ void Scene::deletePictureObject(PictureObject *obj) { MessageQueue *Scene::getMessageQueueById(int messageId) { for (uint i = 0; i < _messageQueueList.size(); i++) - if (((MessageQueue *)_messageQueueList[i])->_dataId == messageId) - return (MessageQueue *)_messageQueueList[i]; + if (_messageQueueList[i]->_dataId == messageId) + return _messageQueueList[i]; return 0; } MessageQueue *Scene::getMessageQueueByName(char *name) { for (uint i = 0; i < _messageQueueList.size(); i++) - if (!strcmp(((MessageQueue *)_messageQueueList[i])->_queueName, name)) - return (MessageQueue *)_messageQueueList[i]; + if (!strcmp(_messageQueueList[i]->_queueName, name)) + return _messageQueueList[i]; return 0; } @@ -447,15 +466,27 @@ void Scene::initObjectCursors(const char *varname) { } bool Scene::compareObjPriority(const void *p1, const void *p2) { - if (((const StaticANIObject *)p1)->_priority > ((const StaticANIObject *)p2)->_priority) + if (((const GameObject *)p1)->_priority > ((const GameObject *)p2)->_priority) return true; return false; } -void Scene::objectList_sortByPriority(PtrList &list, bool skipFirst) { +void Scene::objectList_sortByPriority(Common::Array<StaticANIObject *> &list, bool skipFirst) { if (skipFirst) { - PtrList::iterator s = list.begin(); + Common::Array<StaticANIObject *>::iterator s = list.begin(); + + ++s; + + Common::sort(s, list.end(), Scene::compareObjPriority); + } else { + Common::sort(list.begin(), list.end(), Scene::compareObjPriority); + } +} + +void Scene::objectList_sortByPriority(Common::Array<PictureObject *> &list, bool skipFirst) { + if (skipFirst) { + Common::Array<PictureObject *>::iterator s = list.begin(); ++s; @@ -476,16 +507,15 @@ void Scene::draw() { objectList_sortByPriority(_staticANIObjectList2); - for (PtrList::iterator s = _staticANIObjectList2.begin(); s != _staticANIObjectList2.end(); ++s) { - ((StaticANIObject *)*s)->draw2(); - } + for (uint i = 0; i < _staticANIObjectList2.size(); i++) + _staticANIObjectList2[i]->draw2(); int priority = -1; - for (PtrList::iterator s = _staticANIObjectList2.begin(); s != _staticANIObjectList2.end(); ++s) { - drawContent(((StaticANIObject *)*s)->_priority, priority, false); - ((StaticANIObject *)*s)->draw(); + for (uint i = 0; i < _staticANIObjectList2.size(); i++) { + drawContent(_staticANIObjectList2[i]->_priority, priority, false); + _staticANIObjectList2[i]->draw(); - priority = ((StaticANIObject *)*s)->_priority; + priority = _staticANIObjectList2[i]->_priority; } drawContent(-1, priority, false); @@ -566,7 +596,7 @@ StaticANIObject *Scene::getStaticANIObjectAtPos(int x, int y) { StaticANIObject *res = 0; for (uint i = 0; i < _staticANIObjectList1.size(); i++) { - StaticANIObject *p = (StaticANIObject *)_staticANIObjectList1[i]; + StaticANIObject *p = _staticANIObjectList1[i]; int pixel; if ((p->_field_8 & 0x100) && (p->_flags & 4) && @@ -612,8 +642,8 @@ int Scene::getPictureObjectIdAtPos(int x, int y) { void Scene::update(int counterdiff) { debug(6, "Scene::update(%d)", counterdiff); - for (PtrList::iterator s = _staticANIObjectList2.begin(); s != _staticANIObjectList2.end(); ++s) - ((StaticANIObject *)*s)->update(counterdiff); + for (uint i = 0; i < _staticANIObjectList2.size(); i++) + _staticANIObjectList2[i]->update(counterdiff); } void Scene::drawContent(int minPri, int maxPri, bool drawBg) { diff --git a/engines/fullpipe/scene.h b/engines/fullpipe/scene.h index 8306974f7b..1e2dae81fe 100644 --- a/engines/fullpipe/scene.h +++ b/engines/fullpipe/scene.h @@ -31,10 +31,10 @@ class MessageQueue; class Scene : public Background { public: - PtrList _staticANIObjectList1; - PtrList _staticANIObjectList2; - PtrList _messageQueueList; - PtrList _faObjectList; + Common::Array<StaticANIObject *> _staticANIObjectList1; + Common::Array<StaticANIObject *> _staticANIObjectList2; + Common::Array<MessageQueue *> _messageQueueList; + // PtrList _faObjectList; // not used Shadows *_shadows; SoundList *_soundList; int16 _sceneId; @@ -82,7 +82,8 @@ class Scene : public Background { private: static bool compareObjPriority(const void *p1, const void *p2); - void objectList_sortByPriority(PtrList &list, bool skipFirst = false); + void objectList_sortByPriority(Common::Array<StaticANIObject *> &list, bool skipFirst = false); + void objectList_sortByPriority(Common::Array<PictureObject *> &list, bool skipFirst = false); }; class SceneTag : public CObject { diff --git a/engines/fullpipe/scenes.cpp b/engines/fullpipe/scenes.cpp index 7420c1b1cf..b346bf3a17 100644 --- a/engines/fullpipe/scenes.cpp +++ b/engines/fullpipe/scenes.cpp @@ -590,10 +590,8 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) { scene->setPictureObjectsFlag4(); - for (PtrList::iterator s = scene->_staticANIObjectList1.begin(); s != scene->_staticANIObjectList1.end(); ++s) { - StaticANIObject *o = (StaticANIObject *)*s; - o->setFlags(o->_flags & 0xFE7F); - } + for (uint i = 0; i < scene->_staticANIObjectList1.size(); i++) + scene->_staticANIObjectList1[i]->_flags &= 0xFE7F; PictureObject *p = accessScene(SC_INV)->getPictureObjectById(PIC_INV_MENU, 0); p->setFlags(p->_flags & 0xFFFB); @@ -1456,9 +1454,28 @@ void BallChain::init(Ball **ball) { } Ball *BallChain::sub04(Ball *ballP, Ball *ballN) { - warning("STUB: BallChain::sub04"); + if (!pTail) { + cPlex = (byte *)calloc(cPlexLen, sizeof(Ball)); + + Ball *runPtr = (Ball *)&cPlex[(cPlexLen - 1) * sizeof(Ball)]; + + for (int i = 0; i < cPlexLen; i++) { + runPtr->p0 = pTail; + pTail = runPtr; + + runPtr -= sizeof(Ball); + } + } + + Ball *res = pTail; + + pTail = res->p0; + res->p1 = ballP; + res->p0 = ballN; + numBalls++; + res->ani = 0; - return pTail; + return res; } void BallChain::removeBall(Ball *ball) { diff --git a/engines/fullpipe/sound.cpp b/engines/fullpipe/sound.cpp index 3c13bad854..65c9bf84ca 100644 --- a/engines/fullpipe/sound.cpp +++ b/engines/fullpipe/sound.cpp @@ -27,6 +27,8 @@ #include "fullpipe/sound.h" #include "fullpipe/ngiarchive.h" #include "fullpipe/messages.h" +#include "fullpipe/statics.h" + #include "common/memstream.h" #include "audio/audiostream.h" #include "audio/decoders/vorbis.h" @@ -132,7 +134,75 @@ void Sound::updateVolume() { } void Sound::setPanAndVolumeByStaticAni() { - debug(3, "STUB Sound::setPanAndVolumeByStaticAni()"); + if (!_objectId) + return; + + StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(_objectId, -1); + if (!ani) + return; + + int a, b; + + if (ani->_ox >= g_fp->_sceneRect.left) { + int par, pan; + + if (ani->_ox <= g_fp->_sceneRect.right) { + int dx; + + if (ani->_oy <= g_fp->_sceneRect.bottom) { + if (ani->_oy >= g_fp->_sceneRect.top) { + setPanAndVolume(g_fp->_sfxVolume, 0); + + return; + } + dx = g_fp->_sceneRect.top - ani->_oy; + } else { + dx = ani->_oy - g_fp->_sceneRect.bottom; + } + + par = 0; + + if (dx > 800) { + setPanAndVolume(-3500, 0); + return; + } + + pan = -3500; + a = g_fp->_sfxVolume - (-3500); + b = 800 - dx; + } else { + int dx = ani->_ox - g_fp->_sceneRect.right; + + if (dx > 800) { + setPanAndVolume(-3500, 0); + return; + } + + pan = -3500; + par = dx * (-3500) / -800; + a = g_fp->_sfxVolume - (-3500); + b = 800 - dx; + } + + int32 pp = b * a; + + setPanAndVolume(pan + pp / 800, par); + + return; + } + + int dx = g_fp->_sceneRect.left - ani->_ox; + if (dx <= 800) { + int32 s = (800 - dx) * (g_fp->_sfxVolume - (-3500)); + int32 p = -3500 + s / 800; + + if (p > g_fp->_sfxVolume) + p = g_fp->_sfxVolume; + + setPanAndVolume(p, dx * (-3500) / 800); + } else { + setPanAndVolume(-3500, 0); + } } void Sound::setPanAndVolume(int vol, int pan) { @@ -298,8 +368,12 @@ void FullpipeEngine::startSoundStream1(char *trackName) { } void FullpipeEngine::stopAllSounds() { - // TODO: Differences from stopAllSoundStreams() - _mixer->stopAll(); + // _mixer->stopAll(); + + for (int i = 0; i < _currSoundListCount; i++) + for (int j = 0; j < _currSoundList1[i]->getCount(); j++) { + _currSoundList1[i]->getSoundByIndex(j)->stop(); + } } void FullpipeEngine::toggleMute() { @@ -447,7 +521,7 @@ void FullpipeEngine::updateSoundVolume() { void FullpipeEngine::setMusicVolume(int vol) { _musicVolume = vol; - debug(3, "STUB FullpipeEngine::setMusicVolume()"); + g_fp->_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, vol); } } // End of namespace Fullpipe diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp index e36b196517..41641457d3 100644 --- a/engines/fullpipe/stateloader.cpp +++ b/engines/fullpipe/stateloader.cpp @@ -55,9 +55,8 @@ bool FullpipeEngine::loadGam(const char *fname, int scene) { _inventory->rebuildItemRects(); - for (PtrList::iterator p = _inventory->getScene()->_picObjList.begin(); p != _inventory->getScene()->_picObjList.end(); ++p) { - ((MemoryObject *)((PictureObject *)*p)->_picture)->load(); - } + for (uint i = 0; i < _inventory->getScene()->_picObjList.size(); i++) + ((MemoryObject *)_inventory->getScene()->_picObjList[i]->_picture)->load(); // _sceneSwitcher = sceneSwitcher; // substituted with direct call _gameLoader->_preloadCallback = preloadCallback; diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp index f1abac5778..b6b312ab85 100644 --- a/engines/fullpipe/statics.cpp +++ b/engines/fullpipe/statics.cpp @@ -141,7 +141,17 @@ StaticANIObject::StaticANIObject() { } StaticANIObject::~StaticANIObject() { - warning("STUB: StaticANIObject::~StaticANIObject()"); + for (uint i = 0; i < _staticsList.size(); i++) + delete _staticsList[i]; + + _staticsList.clear(); + + for (uint i = 0; i < _movements.size(); i++) + delete _movements[i]; + + _movements.clear(); + + g_fp->_mgm->clear(); } StaticANIObject::StaticANIObject(StaticANIObject *src) : GameObject(src) { @@ -164,22 +174,21 @@ StaticANIObject::StaticANIObject(StaticANIObject *src) : GameObject(src) { _objtype = kObjTypeStaticANIObject; for (uint i = 0; i < src->_staticsList.size(); i++) - _staticsList.push_back(new Statics((Statics *)src->_staticsList[i], 0)); + _staticsList.push_back(new Statics(src->_staticsList[i], 0)); _movement = 0; _statics = 0; for (uint i = 0; i < src->_movements.size(); i++) { Movement *newmov; - Movement *mov = (Movement *)src->_movements[i]; - if (mov->_currMovement) { + if (src->_movements[i]->_currMovement) { // WORKAROUND: Original uses weird construction here: // new Movement(getMovementById(src->getMovementIdById(mov->_id)), this); - newmov = new Movement(src->getMovementById(src->getMovementIdById(mov->_id)), this); - newmov->_id = mov->_id; + newmov = new Movement(src->getMovementById(src->getMovementIdById(src->_movements[i]->_id)), this); + newmov->_id = src->_movements[i]->_id; } else { - newmov = new Movement(mov, 0, -1, this); + newmov = new Movement(src->_movements[i], 0, -1, this); } _movements.push_back(newmov); @@ -224,7 +233,7 @@ bool StaticANIObject::load(MfcArchive &file) { Common::Point pt; if (count) { // We have movements - ((Movement *)_movements[0])->getCurrDynamicPhaseXY(pt); + _movements[0]->getCurrDynamicPhaseXY(pt); } else { pt.x = pt.y = 100; } @@ -392,34 +401,36 @@ bool StaticANIObject::isIdle() { Statics *StaticANIObject::getStaticsById(int itemId) { for (uint i = 0; i < _staticsList.size(); i++) - if (((Statics *)_staticsList[i])->_staticsId == itemId) - return (Statics *)_staticsList[i]; + if (_staticsList[i]->_staticsId == itemId) + return _staticsList[i]; return 0; } Statics *StaticANIObject::getStaticsByName(char *name) { for (uint i = 0; i < _staticsList.size(); i++) - if (!strcmp(((Statics *)_staticsList[i])->_staticsName, name)) - return (Statics *)_staticsList[i]; + if (!strcmp(_staticsList[i]->_staticsName, name)) + return _staticsList[i]; return 0; } Movement *StaticANIObject::getMovementById(int itemId) { for (uint i = 0; i < _movements.size(); i++) - if (((Movement *)_movements[i])->_id == itemId) - return (Movement *)_movements[i]; + if (_movements[i]->_id == itemId) + return _movements[i]; return 0; } int StaticANIObject::getMovementIdById(int itemId) { for (uint i = 0; i < _movements.size(); i++) { - Movement *mov = (Movement *)_movements[i]; + Movement *mov = _movements[i]; + if (mov->_currMovement) { if (mov->_id == itemId) return mov->_id; + if (mov->_currMovement->_id == itemId) return mov->_id; } @@ -430,8 +441,8 @@ int StaticANIObject::getMovementIdById(int itemId) { Movement *StaticANIObject::getMovementByName(char *name) { for (uint i = 0; i < _movements.size(); i++) - if (!strcmp(((Movement *)_movements[i])->_objectName, name)) - return (Movement *)_movements[i]; + if (!strcmp(_movements[i]->_objectName, name)) + return _movements[i]; return 0; } @@ -551,12 +562,12 @@ void Movement::draw(bool flipFlag, int angle) { void StaticANIObject::loadMovementsPixelData() { for (uint i = 0; i < _movements.size(); i++) - ((Movement *)_movements[i])->loadPixelData(); + _movements[i]->loadPixelData(); } void StaticANIObject::freeMovementsPixelData() { for (uint i = 0; i < _movements.size(); i++) - ((Movement *)_movements[i])->freePixelData(); + _movements[i]->freePixelData(); } Statics *StaticANIObject::addReverseStatics(Statics *st) { @@ -665,11 +676,10 @@ MovTable *StaticANIObject::countMovements() { movTable->movs = (int16 *)calloc(_movements.size(), sizeof(int16)); for (uint i = 0; i < _movements.size(); i++) { - GameObject *obj = (GameObject *)_movements[i]; movTable->movs[i] = 2; for (GameVar *sub = preloadSubVar->_subVars; sub; sub = sub->_nextVarObj) { - if (scumm_stricmp(obj->getName(), sub->_varName) == 0) { + if (scumm_stricmp(_movements[i]->getName(), sub->_varName) == 0) { movTable->movs[i] = 1; break; } @@ -702,21 +712,21 @@ void StaticANIObject::setSpeed(int speed) { void StaticANIObject::setAlpha(int alpha) { for (uint i = 0; i < _movements.size(); i++) - ((Movement *)_movements[i])->setAlpha(alpha); + _movements[i]->setAlpha(alpha); for (uint i = 0; i < _staticsList.size(); i++) - ((Statics *)_staticsList[i])->setAlpha(alpha); + _staticsList[i]->setAlpha(alpha); } void StaticANIObject::initMovements() { for (uint i = 0; i < _movements.size(); i++) - ((Movement *)_movements[i])->removeFirstPhase(); + _movements[i]->removeFirstPhase(); } void StaticANIObject::preloadMovements(MovTable *mt) { - if ( mt ) { + if (mt) { for (uint i = 0; i < _movements.size(); i++) { - Movement *mov = (Movement *)_movements[i]; + Movement *mov = _movements[i]; if (mt->movs[i] == 1) mov->loadPixelData(); @@ -1177,8 +1187,8 @@ void StaticANIObject::startAnimSteps(int movementId, int messageQueueId, int x, if (!(_flags & 0x80)) { if (!_messageQueueId) for (uint i = 0; i < _movements.size(); i++) { - if (((Movement *)_movements[i])->_id == movementId) { - mov = (Movement *)_movements[i]; + if (_movements[i]->_id == movementId) { + mov = _movements[i]; break; } } @@ -1266,7 +1276,7 @@ bool StaticANIObject::startAnim(int movementId, int messageQueueId, int dynPhase if (_flags & 0x80) return false; - debug(0, "StaticANIObject::startAnim(%d, %d, %d) (%s [%d]) [%d, %d]", movementId, messageQueueId, dynPhaseIdx, transCyrillic((byte *)_objectName), _id, _ox, _oy); + debug(4, "StaticANIObject::startAnim(%d, %d, %d) (%s [%d]) [%d, %d]", movementId, messageQueueId, dynPhaseIdx, transCyrillic((byte *)_objectName), _id, _ox, _oy); if (_messageQueueId) { updateGlobalMessageQueue(messageQueueId, _id); @@ -1276,9 +1286,8 @@ bool StaticANIObject::startAnim(int movementId, int messageQueueId, int dynPhase Movement *mov = 0; for (uint i = 0; i < _movements.size(); i++) { - - if (((Movement *)_movements[i])->_id == movementId) { - mov = (Movement *)_movements[i]; + if (_movements[i]->_id == movementId) { + mov = _movements[i]; break; } } @@ -1441,6 +1450,19 @@ bool Statics::load(MfcArchive &file) { return true; } +void Statics::init() { + Picture::init(); + + if (_staticsId & 0x4000) { + Bitmap *bmp = _bitmap->reverseImage(); + + freePixelData(); + + _bitmap = bmp; + _data = bmp->_pixels; + } +} + Common::Point *Statics::getSomeXY(Common::Point &p) { p.x = _someX; p.y = _someY; @@ -1493,7 +1515,17 @@ Movement::Movement() { } Movement::~Movement() { - warning("STUB: Movement::~Movement()"); + for (uint i = 0; i < _dynamicPhases.size(); i++) + delete _framePosOffsets[i]; + + if (!_currMovement ) { + if (_updateFlag1) + _dynamicPhases.remove_at(0); + + _dynamicPhases.clear(); + } + + free(_framePosOffsets); } Movement::Movement(Movement *src, StaticANIObject *ani) { @@ -1748,11 +1780,11 @@ Common::Point *Movement::calcSomeXY(Common::Point &p, int idx) { void Movement::setAlpha(int alpha) { if (_currMovement) for (uint i = 0; i < _currMovement->_dynamicPhases.size(); i++) { - ((DynamicPhase *)_currMovement->_dynamicPhases[i])->setAlpha(alpha); + _currMovement->_dynamicPhases[i]->setAlpha(alpha); } else for (uint i = 0; i < _dynamicPhases.size(); i++) { - ((DynamicPhase *)_dynamicPhases[i])->setAlpha(alpha); + _dynamicPhases[i]->setAlpha(alpha); } } @@ -1765,9 +1797,9 @@ Common::Point *Movement::getDimensionsOfPhase(Common::Point *p, int phaseIndex) DynamicPhase *dyn; if (_currMovement) - dyn = (DynamicPhase *)_currMovement->_dynamicPhases[idx]; + dyn = _currMovement->_dynamicPhases[idx]; else - dyn = (DynamicPhase *)_dynamicPhases[idx]; + dyn = _dynamicPhases[idx]; Common::Point point; @@ -1816,13 +1848,13 @@ void Movement::updateCurrDynamicPhase() { return; if (_currMovement->_dynamicPhases[_currDynamicPhaseIndex]) - _currDynamicPhase = (DynamicPhase *)_currMovement->_dynamicPhases[_currDynamicPhaseIndex]; + _currDynamicPhase = _currMovement->_dynamicPhases[_currDynamicPhaseIndex]; } else { if (_dynamicPhases.size() == 0 || (uint)_currDynamicPhaseIndex >= _dynamicPhases.size()) return; if (_dynamicPhases[_currDynamicPhaseIndex]) - _currDynamicPhase = (DynamicPhase *)_dynamicPhases[_currDynamicPhaseIndex]; + _currDynamicPhase = _dynamicPhases[_currDynamicPhaseIndex]; } } @@ -1831,11 +1863,11 @@ int Movement::calcDuration() { if (_currMovement) for (uint i = 0; i < _currMovement->_dynamicPhases.size(); i++) { - res += ((DynamicPhase *)_currMovement->_dynamicPhases[i])->_initialCountdown; + res += _currMovement->_dynamicPhases[i]->_initialCountdown; } else for (uint i = 0; i < _dynamicPhases.size(); i++) { - res += ((DynamicPhase *)_dynamicPhases[i])->_initialCountdown; + res += _dynamicPhases[i]->_initialCountdown; } return res; @@ -1876,12 +1908,12 @@ DynamicPhase *Movement::getDynamicPhaseByIndex(int idx) { if (_currMovement->_dynamicPhases.size() == 0 || (uint)idx >= _currMovement->_dynamicPhases.size()) return 0; - return (DynamicPhase *)_currMovement->_dynamicPhases[idx]; + return _currMovement->_dynamicPhases[idx]; } else { if (_dynamicPhases.size() == 0 || (uint)idx >= _dynamicPhases.size()) return 0; - return (DynamicPhase *)_dynamicPhases[idx]; + return _dynamicPhases[idx]; } } @@ -1892,7 +1924,7 @@ void Movement::loadPixelData() { for (uint i = 0; i < _dynamicPhases.size(); i++) { if ((Statics *)_dynamicPhases[i] != mov->_staticsObj2 || !(mov->_staticsObj2->_staticsId & 0x4000)) - ((Statics *)_dynamicPhases[i])->getPixelData(); + _dynamicPhases[i]->getPixelData(); } if (!(mov->_staticsObj1->_staticsId & 0x4000)) @@ -1902,7 +1934,7 @@ void Movement::loadPixelData() { void Movement::freePixelData() { if (!_currMovement) for (uint i = 0; i < _dynamicPhases.size(); i++) - ((DynamicPhase *)_dynamicPhases[i])->freePixelData(); + _dynamicPhases[i]->freePixelData(); if (_staticsObj1) _staticsObj1->freePixelData(); @@ -1934,11 +1966,11 @@ bool Movement::gotoNextFrame(void (*callback1)(int, Common::Point *point, int, i if (!callback2) { if (_currMovement) { if ((uint)_currDynamicPhaseIndex == _currMovement->_dynamicPhases.size() - 1 - && !(((DynamicPhase *)(_currMovement->_dynamicPhases.back()))->_countdown)) { + && !(_currMovement->_dynamicPhases.back()->_countdown)) { return false; } } else if ((uint)_currDynamicPhaseIndex == _dynamicPhases.size() - 1 - && !(((DynamicPhase *)(_dynamicPhases.back()))->_countdown)) { + && !(_dynamicPhases.back()->_countdown)) { return false; } } diff --git a/engines/fullpipe/statics.h b/engines/fullpipe/statics.h index d678957163..63661157b2 100644 --- a/engines/fullpipe/statics.h +++ b/engines/fullpipe/statics.h @@ -98,6 +98,7 @@ class Statics : public DynamicPhase { virtual ~Statics(); virtual bool load(MfcArchive &file); + virtual void init(); Statics *getStaticsById(int itemId); Common::Point *getSomeXY(Common::Point &p); @@ -121,7 +122,7 @@ class Movement : public GameObject { int _field_50; int _counterMax; int _counter; - PtrList _dynamicPhases; + Common::Array<DynamicPhase *> _dynamicPhases; int _field_78; Common::Point **_framePosOffsets; Movement *_currMovement; @@ -181,8 +182,8 @@ class StaticANIObject : public GameObject { int _initialCounter; void (*_callback1)(int, Common::Point *point, int, int); void (*_callback2)(int *); - PtrList _movements; - PtrList _staticsList; + Common::Array<Movement *> _movements; + Common::Array<Statics *> _staticsList; StepArray _stepArray; int16 _field_96; int _messageQueueId; diff --git a/engines/fullpipe/utils.h b/engines/fullpipe/utils.h index 72e746cd03..da3ab7ee4f 100644 --- a/engines/fullpipe/utils.h +++ b/engines/fullpipe/utils.h @@ -68,6 +68,7 @@ enum ObjType { kObjTypeDefault, kObjTypeExCommand, kObjTypeExCommand2, + kObjTypeModalSaveGame, kObjTypeMovGraph, kObjTypeMovGraphLink, kObjTypeMovGraphNode, @@ -148,8 +149,6 @@ class DWordArray : public Common::Array<int32>, public CObject { virtual bool load(MfcArchive &file); }; -typedef Common::Array<void *> PtrList; - char *genFileName(int superId, int sceneId, const char *ext); byte *transCyrillic(byte *s); |
