aboutsummaryrefslogtreecommitdiff
path: root/engines/fullpipe
diff options
context:
space:
mode:
authoruruk2014-05-30 11:14:47 +0200
committeruruk2014-05-30 11:14:47 +0200
commitbb2f8dd68e1d6b2b30b07f60c0cd4e125b47ea4d (patch)
tree9a1e28cfb1eb1a322225c05adc0962a2f96ea521 /engines/fullpipe
parent5ad4e157e5398347651a0da0db07f9daf01bf373 (diff)
parent0a46d67baea121bed0511ce45bfdd8438a43d35d (diff)
downloadscummvm-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.cpp6
-rw-r--r--engines/fullpipe/detection.cpp64
-rw-r--r--engines/fullpipe/fullpipe.cpp52
-rw-r--r--engines/fullpipe/fullpipe.h1
-rw-r--r--engines/fullpipe/gameloader.cpp45
-rw-r--r--engines/fullpipe/gameloader.h16
-rw-r--r--engines/fullpipe/gfx.cpp25
-rw-r--r--engines/fullpipe/gfx.h9
-rw-r--r--engines/fullpipe/messagehandlers.cpp6
-rw-r--r--engines/fullpipe/messages.cpp15
-rw-r--r--engines/fullpipe/modal.cpp185
-rw-r--r--engines/fullpipe/modal.h18
-rw-r--r--engines/fullpipe/motion.cpp866
-rw-r--r--engines/fullpipe/motion.h74
-rw-r--r--engines/fullpipe/scene.cpp106
-rw-r--r--engines/fullpipe/scene.h11
-rw-r--r--engines/fullpipe/scenes.cpp29
-rw-r--r--engines/fullpipe/sound.cpp82
-rw-r--r--engines/fullpipe/stateloader.cpp5
-rw-r--r--engines/fullpipe/statics.cpp126
-rw-r--r--engines/fullpipe/statics.h7
-rw-r--r--engines/fullpipe/utils.h3
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);