diff options
author | uruk | 2014-04-29 11:26:39 +0200 |
---|---|---|
committer | uruk | 2014-04-29 11:26:39 +0200 |
commit | 5b105566a5637edcf73fd6cbc690c1b3b958ff2a (patch) | |
tree | 9b35a6c244e5f9fb7b01be1e6e1da994852534e2 /engines/fullpipe | |
parent | ec71f936280496d349310ea0091dbe26b90ae540 (diff) | |
parent | 55127114349219d57b7a9143a5d3d9bfd97e3e88 (diff) | |
download | scummvm-rg350-5b105566a5637edcf73fd6cbc690c1b3b958ff2a.tar.gz scummvm-rg350-5b105566a5637edcf73fd6cbc690c1b3b958ff2a.tar.bz2 scummvm-rg350-5b105566a5637edcf73fd6cbc690c1b3b958ff2a.zip |
Merge remote-tracking branch 'origin/master' into cge2
Diffstat (limited to 'engines/fullpipe')
-rw-r--r-- | engines/fullpipe/constants.h | 47 | ||||
-rw-r--r-- | engines/fullpipe/fullpipe.cpp | 12 | ||||
-rw-r--r-- | engines/fullpipe/fullpipe.h | 13 | ||||
-rw-r--r-- | engines/fullpipe/input.cpp | 33 | ||||
-rw-r--r-- | engines/fullpipe/messagehandlers.cpp | 62 | ||||
-rw-r--r-- | engines/fullpipe/messages.cpp | 4 | ||||
-rw-r--r-- | engines/fullpipe/messages.h | 1 | ||||
-rw-r--r-- | engines/fullpipe/modal.cpp | 177 | ||||
-rw-r--r-- | engines/fullpipe/modal.h | 37 | ||||
-rw-r--r-- | engines/fullpipe/motion.cpp | 244 | ||||
-rw-r--r-- | engines/fullpipe/motion.h | 5 | ||||
-rw-r--r-- | engines/fullpipe/scenes.cpp | 4 | ||||
-rw-r--r-- | engines/fullpipe/sound.cpp | 301 | ||||
-rw-r--r-- | engines/fullpipe/sound.h | 14 | ||||
-rw-r--r-- | engines/fullpipe/statics.cpp | 55 | ||||
-rw-r--r-- | engines/fullpipe/statics.h | 3 |
16 files changed, 891 insertions, 121 deletions
diff --git a/engines/fullpipe/constants.h b/engines/fullpipe/constants.h index 8f3f587714..b257fca949 100644 --- a/engines/fullpipe/constants.h +++ b/engines/fullpipe/constants.h @@ -43,6 +43,8 @@ namespace Fullpipe { #define MV_LFT_OPEN 1048 #define MV_MAN_GOLADDER 451 #define MV_MAN_GOLADDER2 2844 +#define MV_MAN_HMRKICK 1028 +#define MV_MAN_HMRKICK_COINLESS 1445 #define MV_MAN_LIFTDOWN 1052 #define MV_MAN_LIFTUP 1051 #define MV_MAN_LOOKUP 4773 @@ -219,8 +221,11 @@ namespace Fullpipe { #define SC_MAINMENU 4620 #define SC_MAP 5222 #define SC_TITLES 5166 +#define SND_CMN_015 3139 #define SND_CMN_031 3516 #define SND_CMN_032 3517 +#define SND_CMN_054 4762 +#define SND_CMN_055 4763 #define SND_CMN_060 4921 #define SND_CMN_061 4922 #define SND_CMN_070 5199 @@ -287,6 +292,48 @@ namespace Fullpipe { #define PIC_MOV_CANCEL 5345 #define PIC_MOV_OK 5344 +// Saveload dialog +#define PIC_MLD_BGR 4645 +#define PIC_MLD_CANCEL_D 4648 +#define PIC_MLD_CANCEL_L 4649 +#define PIC_MLD_OK_D 4646 +#define PIC_MLD_OK_L 4647 +#define PIC_MSV_0_D 4643 +#define PIC_MSV_0_L 4644 +#define PIC_MSV_1_D 4651 +#define PIC_MSV_1_L 4660 +#define PIC_MSV_2_D 4652 +#define PIC_MSV_2_L 4661 +#define PIC_MSV_3_D 4653 +#define PIC_MSV_3_L 4662 +#define PIC_MSV_4_D 4654 +#define PIC_MSV_4_L 4663 +#define PIC_MSV_5_D 4655 +#define PIC_MSV_5_L 4664 +#define PIC_MSV_6_D 4656 +#define PIC_MSV_6_L 4665 +#define PIC_MSV_7_D 4657 +#define PIC_MSV_7_L 4666 +#define PIC_MSV_8_D 4658 +#define PIC_MSV_8_L 4667 +#define PIC_MSV_9_D 4659 +#define PIC_MSV_9_L 4668 +#define PIC_MSV_BGR 4634 +#define PIC_MSV_CANCEL_D 4637 +#define PIC_MSV_CANCEL_L 4638 +#define PIC_MSV_DOTS_D 4670 +#define PIC_MSV_DOTS_L 4669 +#define PIC_MSV_DOT_D 5188 +#define PIC_MSV_DOT_L 5189 +#define PIC_MSV_EMPTY_D 4639 +#define PIC_MSV_EMPTY_L 4640 +#define PIC_MSV_FULL_D 4641 +#define PIC_MSV_FULL_L 4642 +#define PIC_MSV_OK_D 4635 +#define PIC_MSV_OK_L 4636 +#define PIC_MSV_SPACE_D 5190 +#define PIC_MSV_SPACE_L 5191 + // Intro #define ANI_IN1MAN 5110 #define MSG_INTR_ENDINTRO 5139 diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp index 246510e227..5369c05de7 100644 --- a/engines/fullpipe/fullpipe.cpp +++ b/engines/fullpipe/fullpipe.cpp @@ -104,6 +104,18 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc) _musicAllowed = -1; _musicGameVar = 0; + _musicMinDelay = 0; + _musicMaxDelay = 0; + _musicLocal = 0; + _trackStartDelay = 0; + + memset(_sceneTracks, 0, sizeof(_sceneTracks)); + memset(_trackName, 0, sizeof(_trackName)); + memset(_sceneTracksCurrentTrack, 0, sizeof(_sceneTracksCurrentTrack)); + + _numSceneTracks = 0; + _sceneTrackHasSequence = false; + _sceneTrackIsPlaying = false; _aniMan = 0; _aniMan2 = 0; diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h index 5718b16ab3..27505252ab 100644 --- a/engines/fullpipe/fullpipe.h +++ b/engines/fullpipe/fullpipe.h @@ -151,12 +151,24 @@ public: int _currSoundListCount; bool _soundEnabled; bool _flgSoundList; + char _sceneTracks[10][260]; + int _numSceneTracks; + bool _sceneTrackHasSequence; + int _musicMinDelay; + int _musicMaxDelay; + int _musicLocal; + char _trackName[2600]; + int _trackStartDelay; + char _sceneTracksCurrentTrack[260]; + bool _sceneTrackIsPlaying; void stopAllSounds(); void toggleMute(); void playSound(int id, int flag); void playTrack(GameVar *sceneVar, const char *name, bool delayed); + int getSceneTrack(); void startSceneTrack(); + void startSoundStream1(char *trackName); void stopSoundStream2(); void stopAllSoundStreams(); void stopAllSoundInstances(int id); @@ -300,6 +312,7 @@ public: GameVar *_musicGameVar; Audio::SoundHandle _sceneTrackHandle; + public: bool _isSaveAllowed; diff --git a/engines/fullpipe/input.cpp b/engines/fullpipe/input.cpp index 0678d15368..7c97461a24 100644 --- a/engines/fullpipe/input.cpp +++ b/engines/fullpipe/input.cpp @@ -275,6 +275,8 @@ void FullpipeEngine::updateCursorCommon() { } void FullpipeEngine::initArcadeKeys(const char *varname) { + _arcadeKeys.clear(); + GameVar *var = getGameLoaderGameVar()->getSubVarByName(varname)->getSubVarByName("KEYPOS"); if (!var) @@ -294,6 +296,37 @@ void FullpipeEngine::initArcadeKeys(const char *varname) { } } +void FullpipeEngine::processArcade(ExCommand *cmd) { + if (!g_fp->_aniMan2) + return; + + int idx; + + if (cmd->_sceneClickX <= g_fp->_aniMan2->_ox) { + for (idx = (int)_arcadeKeys.size() - 1; idx >= 0; idx--) { + if (_arcadeKeys[idx]->x < g_fp->_aniMan2->_ox) + break; + } + + if (idx < 0) + return; + } else { + for (idx = 0; idx < (int)_arcadeKeys.size(); idx++) { + if (_arcadeKeys[idx]->x > g_fp->_aniMan2->_ox) + break; + } + + if (idx >= (int)_arcadeKeys.size()) + return; + } + + cmd->_sceneClickX = _arcadeKeys[idx]->x; + cmd->_sceneClickY = _arcadeKeys[idx]->y; + + cmd->_x = cmd->_sceneClickX - g_fp->_sceneRect.left; + cmd->_y = cmd->_sceneClickY - g_fp->_sceneRect.top; +} + void FullpipeEngine::setArcadeOverlay(int picId) { Common::Point point; Common::Point point2; diff --git a/engines/fullpipe/messagehandlers.cpp b/engines/fullpipe/messagehandlers.cpp index 17af2bf4fd..15aa78d342 100644 --- a/engines/fullpipe/messagehandlers.cpp +++ b/engines/fullpipe/messagehandlers.cpp @@ -34,11 +34,69 @@ namespace Fullpipe { void global_messageHandler_KickStucco() { - warning("STUB: global_messageHandler_KickStucco()"); + Movement *mov = g_fp->_aniMan->getMovementById(MV_MAN_HMRKICK); + int end = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size(); + bool flip = false; + + for (int i = 0; i < end; i++) { + ExCommand *ex = mov->getDynamicPhaseByIndex(i)->_exCommand; + + if (ex) + if (ex->_messageKind == 35) + if (ex->_messageNum == SND_CMN_015) { + if (flip) { + ex->_messageNum = SND_CMN_055; + } else { + ex->_messageNum = SND_CMN_054; + flip = true; + } + } + } + + mov = g_fp->_aniMan->getMovementById(MV_MAN_HMRKICK_COINLESS); + end = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size(); + flip = false; + + for (int i = 0; i < end; i++) { + ExCommand *ex = mov->getDynamicPhaseByIndex(i)->_exCommand; + + if (ex) + if (ex->_messageKind == 35) + if (ex->_messageNum == SND_CMN_015) { + if (flip) { + ex->_messageNum = SND_CMN_055; + } else { + ex->_messageNum = SND_CMN_054; + flip = true; + } + } + } } void global_messageHandler_KickMetal() { - warning("STUB: global_messageHandler_KickMetal()"); + Movement *mov = g_fp->_aniMan->getMovementById(MV_MAN_HMRKICK); + int end = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size(); + + for (int i = 0; i < end; i++) { + ExCommand *ex = mov->getDynamicPhaseByIndex(i)->_exCommand; + + if (ex) + if (ex->_messageKind == 35) + if (ex->_messageNum == SND_CMN_054 || ex->_messageNum == SND_CMN_055) + ex->_messageNum = SND_CMN_015; + } + + mov = g_fp->_aniMan->getMovementById(MV_MAN_HMRKICK_COINLESS); + end = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size(); + + for (int i = 0; i < end; i++) { + ExCommand *ex = mov->getDynamicPhaseByIndex(i)->_exCommand; + + if (ex) + if (ex->_messageKind == 35) + if (ex->_messageNum == SND_CMN_054 || ex->_messageNum == SND_CMN_055) + ex->_messageNum = SND_CMN_015; + } } int global_messageHandler1(ExCommand *cmd) { diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp index 9c8f5ac4e2..8257d1459f 100644 --- a/engines/fullpipe/messages.cpp +++ b/engines/fullpipe/messages.cpp @@ -699,6 +699,10 @@ void GlobalMessageQueueList::addMessageQueue(MessageQueue *msg) { push_back(msg); } +void clearGlobalMessageQueueList() { + g_fp->_globalMessageQueueList->clear(); +} + void clearGlobalMessageQueueList1() { clearMessages(); diff --git a/engines/fullpipe/messages.h b/engines/fullpipe/messages.h index da579d58c0..e6f7f05150 100644 --- a/engines/fullpipe/messages.h +++ b/engines/fullpipe/messages.h @@ -193,6 +193,7 @@ void clearMessageHandlers(); void processMessages(); void updateGlobalMessageQueue(int id, int objid); void clearMessages(); +void clearGlobalMessageQueueList(); void clearGlobalMessageQueueList1(); bool chainQueue(int queueId, int flags); diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp index 65274bfcf1..bba5df0cd5 100644 --- a/engines/fullpipe/modal.cpp +++ b/engines/fullpipe/modal.cpp @@ -1446,18 +1446,187 @@ bool ModalQuery::init(int counterdiff) { } ModalSaveGame::ModalSaveGame() { - warning("STUB: ModalSaveGame::ModalSaveGame()"); - _oldBgX = 0; _oldBgY = 0; + + _bgr = 0; + _okD = 0; + _okL = 0; + _cancelD = 0; + _cancelL = 0; + _emptyD = 0; + _emptyL = 0; + _queryRes = -1; + _rect = g_fp->_sceneRect; + _queryDlg = 0; + _mode = 1; +} + +ModalSaveGame::~ModalSaveGame() { + g_fp->_sceneRect = _rect; + + _arrayD.clear(); + _arrayL.clear(); + + for (uint i = 0; i < _files.size(); i++) + free(_files[i]); + + _files.clear(); } void ModalSaveGame::setScene(Scene *sc) { - warning("STUB: ModalSaveGame::setScene()"); + _queryRes = -1; + _menuScene = sc; +} + +void ModalSaveGame::processKey(int key) { + if (key == 27) + _queryRes = 0; +} + +bool ModalSaveGame::init(int counterdiff) { + if (_queryDlg) { + if (!_queryDlg->init(counterdiff)) { + if (!_queryDlg->getQueryResult()) + _queryRes = -1; + + delete _queryDlg; + _queryDlg = 0; + } + + return true; + } + + if (_queryRes == -1) + return true; + + g_fp->_sceneRect = _rect; + + if (g_fp->_currentScene) { + g_fp->_currentScene->_x = _oldBgX; + g_fp->_currentScene->_y = _oldBgY; + } + + if (!_queryRes) { + ModalMainMenu *m = new ModalMainMenu; + + g_fp->_modalObject = m; + + m->_parentObj = _parentObj; + m->_screct = _rect; + m->_bgX = _oldBgX; + m->_bgY = _oldBgY; + + delete this; + + return true; + } + + return false; } void ModalSaveGame::setup(Scene *sc, int mode) { - warning("STUB: ModalSaveGame::setup()"); + _files.clear(); + _arrayL.clear(); + _arrayD.clear(); + _mode = mode; + + if (mode) { + _bgr = sc->getPictureObjectById(PIC_MSV_BGR, 0); + _cancelD = sc->getPictureObjectById(PIC_MSV_CANCEL_D, 0); + _cancelL = sc->getPictureObjectById(PIC_MSV_CANCEL_L, 0); + _okD = sc->getPictureObjectById(PIC_MSV_OK_D, 0); + _okL = sc->getPictureObjectById(PIC_MSV_OK_L, 0); + _emptyD = sc->getPictureObjectById(PIC_MSV_EMPTY_D, 0); + _emptyL = sc->getPictureObjectById(PIC_MSV_EMPTY_L, 0); + } else { + _bgr = sc->getPictureObjectById(PIC_MLD_BGR, 0); + _cancelD = sc->getPictureObjectById(PIC_MLD_CANCEL_D, 0); + _cancelL = sc->getPictureObjectById(PIC_MLD_CANCEL_L, 0); + _okD = sc->getPictureObjectById(PIC_MLD_OK_D, 0); + _okL = sc->getPictureObjectById(PIC_MLD_OK_L, 0); + _emptyD = sc->getPictureObjectById(PIC_MSV_EMPTY_D, 0); + _emptyL = sc->getPictureObjectById(PIC_MSV_EMPTY_D, 0); + } + + _fullD = sc->getPictureObjectById(PIC_MSV_FULL_D, 0); + _fullL = sc->getPictureObjectById(PIC_MSV_FULL_L, 0); + _queryRes = -1; + + _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_0_D, 0)); + _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_0_L, 0)); + _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_1_D, 0)); + _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_1_L, 0)); + _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_2_D, 0)); + _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_2_L, 0)); + _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_3_D, 0)); + _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_3_L, 0)); + _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_4_D, 0)); + _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_4_L, 0)); + _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_5_D, 0)); + _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_5_L, 0)); + _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_6_D, 0)); + _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_6_L, 0)); + _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_7_D, 0)); + _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_7_L, 0)); + _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_8_D, 0)); + _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_8_L, 0)); + _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_9_D, 0)); + _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_9_L, 0)); + _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_DOTS_D, 0)); + _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_DOTS_L, 0)); + _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_DOT_D, 0)); + _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_DOT_L, 0)); + _arrayL.push_back(sc->getPictureObjectById(PIC_MSV_SPACE_D, 0)); + _arrayD.push_back(sc->getPictureObjectById(PIC_MSV_SPACE_L, 0)); + + Common::Point point; + + int x = _bgr->_ox + _bgr->getDimensions(&point)->x / 2; + int y = _bgr->_oy + 90; + int w; + FileInfo *fileinfo; + + for (int i = 0; i < 7; i++) { + fileinfo = new FileInfo; + memset(fileinfo, 0, sizeof(FileInfo)); + + snprintf(fileinfo->filename, 160, "save%02d.sav", i); + + if (!getFileInfo(fileinfo->filename, fileinfo)) { + fileinfo->empty = true; + w = _emptyD->getDimensions(&point)->x; + } else { + w = 0; + + for (int j = 0; j < 16; j++) { + _arrayL[j]->getDimensions(&point); + w += point.x + 2; + } + } + + fileinfo->fx1 = x - w / 2; + fileinfo->fx2 = x + w / 2; + fileinfo->fy1 = y; + fileinfo->fy2 = y + _emptyD->getDimensions(&point)->y; + + _files.push_back(fileinfo); + + y = fileinfo->fy2 + 3; + } +} + +char *ModalSaveGame::getSaveName() { + if (_queryRes < 0) + return 0; + + return _files[_queryRes]->filename; +} + +bool ModalSaveGame::getFileInfo(char *filename, FileInfo *fileinfo) { + warning("STUB: ModalSaveGame::getFileInfo()"); + + return false; } void FullpipeEngine::openHelp() { diff --git a/engines/fullpipe/modal.h b/engines/fullpipe/modal.h index f7264057fb..a214b1c639 100644 --- a/engines/fullpipe/modal.h +++ b/engines/fullpipe/modal.h @@ -29,6 +29,19 @@ class PictureObject; class Picture; class Sound; +struct FileInfo { + char filename[260]; + bool empty; + int day; + int month; + int year; + int time; + int fx1; + int fx2; + int fy1; + int fy2; +}; + class BaseModalObject { public: @@ -240,20 +253,40 @@ private: class ModalSaveGame : public BaseModalObject { public: ModalSaveGame(); - virtual ~ModalSaveGame() {} + virtual ~ModalSaveGame(); virtual bool pollEvent() { return true; } virtual bool handleMessage(ExCommand *message) { return false; } - virtual bool init(int counterdiff) { return true; } + virtual bool init(int counterdiff); virtual void update() {} virtual void saveload() {} void setScene(Scene *sc); void setup(Scene *sc, int mode); + void processKey(int key); + + char *getSaveName(); + bool getFileInfo(char *filename, FileInfo *fileinfo); Common::Rect _rect; int _oldBgX; int _oldBgY; + PictureObject *_bgr; + PictureObject *_okD; + PictureObject *_okL; + PictureObject *_cancelD; + PictureObject *_cancelL; + PictureObject *_emptyD; + PictureObject *_emptyL; + PictureObject *_fullD; + PictureObject *_fullL; + Scene *_menuScene; + int _mode; + ModalQuery *_queryDlg; + Common::Array <FileInfo *> _files; + Common::Array <PictureObject *> _arrayL; + Common::Array <PictureObject *> _arrayD; + int _queryRes; }; diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp index f40c1ae08b..35da154570 100644 --- a/engines/fullpipe/motion.cpp +++ b/engines/fullpipe/motion.cpp @@ -1824,6 +1824,89 @@ void MGM::clear() { _items.clear(); } +MessageQueue *MGM::genMQ(StaticANIObject *ani, int staticsIndex, int staticsId, int *resStatId, Common::Point **pointArr) { + int idx = getItemIndexById(ani->_id); + + if (idx == -1) + return 0; + + int stid = staticsId; + + if (!staticsId) { + if (ani->_movement) { + stid = ani->_movement->_staticsObj2->_staticsId; + } else { + if (!ani->_statics) + return 0; + + stid = ani->_statics->_staticsId; + } + } + + if (stid == staticsIndex) + return new MessageQueue(g_fp->_globalMessageQueueList->compact()); + + int startidx = getStaticsIndexById(idx, stid); + int endidx = getStaticsIndexById(idx, staticsIndex); + int subidx = startidx + endidx * _items[idx]->statics.size(); + + if (!_items[idx]->subItems[subidx]->movement) { + clearMovements2(idx); + recalcOffsets(idx, startidx, endidx, 0, 1); + } + + if (!_items[idx]->subItems[subidx]->movement) + return 0; + + MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact()); + Common::Point point; + ExCommand *ex; + + int i = 0; + do { + subidx = startidx + endidx * _items[idx]->statics.size(); + + _items[idx]->subItems[subidx]->movement->calcSomeXY(point, 0); + + if (pointArr) { + int sz; + + if (_items[idx]->subItems[subidx]->movement->_currMovement) + sz = _items[idx]->subItems[subidx]->movement->_currMovement->_dynamicPhases.size(); + else + sz = _items[idx]->subItems[subidx]->movement->_dynamicPhases.size(); + + ex = new ExCommand2(20, ani->_id, &pointArr[i], sz); + + ex->_messageNum = _items[idx]->subItems[subidx]->movement->_id; + } else { + ex = new ExCommand(ani->_id, 1, _items[idx]->subItems[subidx]->movement->_id, 0, 0, 0, 1, 0, 0, 0); + } + + ex->_keyCode = ani->_okeyCode; + ex->_field_3C = 1; + ex->_field_24 = 1; + + mq->addExCommandToEnd(ex); + + if (resStatId) + *resStatId = _items[idx]->subItems[subidx]->movement->_id; + + startidx = _items[idx]->subItems[subidx]->staticsIndex; + + uint step; + + if (_items[idx]->subItems[subidx]->movement->_currMovement) + step = _items[idx]->subItems[subidx]->movement->_currMovement->_dynamicPhases.size(); + else + step = _items[idx]->subItems[subidx]->movement->_dynamicPhases.size(); + + i += step; + } while (startidx != endidx); + + return mq; +} + MGMItem::MGMItem() { objId = 0; } @@ -1881,15 +1964,10 @@ int MGM::getItemIndexById(int objId) { } MessageQueue *MGM::genMovement(MGMInfo *mgminfo) { - warning("STUB: MGM::genMovement()"); - - return 0; - -#if 0 if (!mgminfo->ani) return 0; - mov = mgminfo->ani->_movement; + Movement *mov = mgminfo->ani->_movement; if (!mov && !mgminfo->ani->_statics) return 0; @@ -1901,14 +1979,17 @@ MessageQueue *MGM::genMovement(MGMInfo *mgminfo) { mgminfo->staticsId1 = mgminfo->ani->_statics->_staticsId; } + Common::Point point; + if (!(mgminfo->flags & 0x10) || !(mgminfo->flags & 0x20)) { int nx = mgminfo->ani->_ox; int ny = mgminfo->ani->_oy; if (mgminfo->ani->_movement) { - mgminfo->ani->calcNextStep(&point2); - nx += point2.x; - ny += point2.y; + mgminfo->ani->calcNextStep(&point); + + nx += point.x; + ny += point.y; } if (!(mgminfo->flags & 0x10)) @@ -1923,40 +2004,37 @@ MessageQueue *MGM::genMovement(MGMInfo *mgminfo) { if (!mov) return 0; - itemIdx = getItemIndexById(mgminfo->ani->_id); - subIdx = getStaticsIndexById(itemIdx, mgminfo->staticsId1); - st2idx = getStaticsIndexById(itemIdx, mov->_staticsObj1->_staticsId); - st1idx = getStaticsIndexById(itemIdx, mov->_staticsObj2->_staticsId); - subOffset = getStaticsIndexById(itemIdx, mgminfo->staticsId2); + int itemIdx = getItemIndexById(mgminfo->ani->_id); + int subIdx = getStaticsIndexById(itemIdx, mgminfo->staticsId1); + int st2idx = getStaticsIndexById(itemIdx, mov->_staticsObj1->_staticsId); + int st1idx = getStaticsIndexById(itemIdx, mov->_staticsObj2->_staticsId); + int subOffset = getStaticsIndexById(itemIdx, mgminfo->staticsId2); clearMovements2(itemIdx); recalcOffsets(itemIdx, subIdx, st2idx, 0, 1); clearMovements2(itemIdx); recalcOffsets(itemIdx, st1idx, subOffset, 0, 1); - v71 = (Message *)(28 * itemIdx); - v16 = items[itemIdx].objId; - v17 = *(_DWORD *)(v16 + offsetof(MGMItem, staticsListCount)); - off = *(_DWORD *)(v16 + offsetof(MGMItem, subItems)); - v18 = (MGMSubItem *)(off + 24 * (subIdx + st2idx * v17)); - x1 = (int)&v18->movement->go.CObject.vmt; - v19 = (MGMSubItem *)(off + 24 * (st1idx + subOffset * v17)); - v69 = (LONG)&v19->movement->go.CObject.vmt; + MGMSubItem *sub1 = _items[itemIdx]->subItems[subIdx + st2idx * _items[itemIdx]->statics.size()]; + MGMSubItem *sub2 = _items[itemIdx]->subItems[st1idx + subOffset * _items[itemIdx]->statics.size()]; - if (subIdx != st2idx && !x1) + if (subIdx != st2idx && !sub1->movement) return 0; - if (st1idx != subOffset && !v69) + if (st1idx != subOffset && !sub2->movement) return 0; - int n1x = mgminfo->x1 - mgminfo->x2 - v18->x - v19->x; - int n1y = mgminfo->y1 - mgminfo->y2 - v18->y - v19->y; + int n1x = mgminfo->x1 - mgminfo->x2 - sub1->x - sub2->x; + int n1y = mgminfo->y1 - mgminfo->y2 - sub1->y - sub2->y; - mov->calcSomeXY(&point1, 0); + Common::Point point1; + + mov->calcSomeXY(point1, 0); int n2x = point1.x; int n2y = point1.y; int mult; + int len; if (mgminfo->flags & 0x40) { mult = mgminfo->field_10; @@ -1973,20 +2051,20 @@ MessageQueue *MGM::genMovement(MGMInfo *mgminfo) { len = -1; n2x = mult * point1.x; n1x = mult * point1.x; - mgminfo->x1 = mgminfo->x2 + mult * point1.x + v18->x + v19->x; + mgminfo->x1 = mgminfo->x2 + mult * point1.x + sub1->x + sub2->x; } if (!(mgminfo->flags & 4)) { n2y = mult * point1.y; n1y = mult * point1.y; len = -1; - mgminfo->y1 = mgminfo->y2 + mult * point1.y + v18->y + v19->y; + mgminfo->y1 = mgminfo->y2 + mult * point1.y + sub1->y + sub2->y; } int px = 0; int py = 0; - if (x1) { + if (sub1->movement) { px = countPhases(itemIdx, subIdx, st2idx, 1); py = countPhases(itemIdx, subIdx, st2idx, 2); } @@ -2001,13 +2079,14 @@ MessageQueue *MGM::genMovement(MGMInfo *mgminfo) { py += mov->countPhasesWithFlag(len, 2); } - if (v69) { + if (sub2->movement) { px += countPhases(itemIdx, st1idx, subOffset, 1); py += countPhases(itemIdx, st1idx, subOffset, 2); } int dx1 = n1x - n2x; int dy1 = n1y - n2y; + int x1, y1; if (px) { x1 = (int)((double)dx1 / (double)px); @@ -2021,6 +2100,8 @@ MessageQueue *MGM::genMovement(MGMInfo *mgminfo) { y1 = 0; } + Common::Point x2, y2; + y2.x = dx1 - px * x1; y2.y = dy1 - py * y1; @@ -2037,16 +2118,19 @@ MessageQueue *MGM::genMovement(MGMInfo *mgminfo) { MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact()); ExCommand2 *ex2; - for (v42 = subIdx; v42 != st2idx; v42 = v43->staticsIndex) { - v43 = &(*(MGMSubItem **)((char *)&this->items->subItems + (unsigned int)v71))[v42 + st2idx * *(int *)((char *)&this->items->staticsListCount + (unsigned int)v71)]; - ex2 = buildExCommand2(v43->movement, mgminfo->ani->go._id, x1, y1, &x2, &y2, -1); + for (int i = subIdx; i != st2idx;) { + MGMSubItem *s = _items[itemIdx]->subItems[i + subOffset * _items[itemIdx]->statics.size()]; + + ex2 = buildExCommand2(s->movement, mgminfo->ani->_id, x1, y1, &x2, &y2, -1); ex2->_parId = mq->_id; ex2->_keyCode = mgminfo->ani->_okeyCode; mq->addExCommandToEnd(ex2); + + i = s->staticsIndex; } - for (i = 0; i < mult; ++i) { + for (int i = 0; i < mult; ++i) { int plen; if (i == mult - 1) @@ -2061,14 +2145,16 @@ MessageQueue *MGM::genMovement(MGMInfo *mgminfo) { mq->addExCommandToEnd(ex2); } - for (j = st1idx; j != subOffset; j = v50->staticsIndex) { - v50 = &(*(MGMSubItem **)((char *)&this->items->subItems + (unsigned int)v71))[j + subOffset * *(int *)((char *)&this->items->staticsListCount + (unsigned int)v71)]; + for (int j = st1idx; j != subOffset;) { + MGMSubItem *s = _items[itemIdx]->subItems[j + subOffset * _items[itemIdx]->statics.size()]; - ex2 = buildExCommand2(v50->movement, mgminfo->ani->_id, x1, y1, &x2, &y2, -1); + ex2 = buildExCommand2(s->movement, mgminfo->ani->_id, x1, y1, &x2, &y2, -1); ex2->_parId = mq->_id; ex2->_keyCode = mgminfo->ani->_okeyCode; mq->addExCommandToEnd(ex2); + + j = s->staticsIndex; } ExCommand *ex = new ExCommand(mgminfo->ani->_id, 5, -1, mgminfo->x1, mgminfo->y1, 0, 1, 0, 0, 0); @@ -2081,9 +2167,25 @@ MessageQueue *MGM::genMovement(MGMInfo *mgminfo) { mq->addExCommandToEnd(ex); return mq; -#endif } +int MGM::countPhases(int idx, int subIdx, int endIdx, int flag) { + int res = 0; + + if (endIdx < 0) + return 0; + + while (subIdx != endIdx) { + if (subIdx < 0) + break; + + res += _items[idx]->subItems[subIdx + endIdx * _items[idx]->statics.size()]->movement->countPhasesWithFlag(-1, flag); + + subIdx = _items[idx]->subItems[subIdx + 6 * endIdx * _items[idx]->statics.size()]->staticsIndex; + } + + return res; +} void MGM::updateAnimStatics(StaticANIObject *ani, int staticsId) { if (getItemIndexById(ani->_id) == -1) return; @@ -2182,9 +2284,8 @@ void MGM::clearMovements2(int idx) { } int MGM::recalcOffsets(int idx, int st1idx, int st2idx, bool flip, bool flop) { -#if 0 MGMItem *item = _items[idx]; - int subIdx = st1idx + st2idx * item->staticsListCount; + int subIdx = st1idx + st2idx * item->statics.size(); if (st1idx == st2idx) { memset(&item->subItems[subIdx], 0, sizeof(item->subItems[subIdx])); @@ -2196,8 +2297,8 @@ int MGM::recalcOffsets(int idx, int st1idx, int st2idx, bool flip, bool flop) { Common::Point point; - for (int i = 0; i < item->movementListCount; i++) { - mov = item->movements1[i]; + for (uint i = 0; i < item->movements1.size(); i++) { + Movement *mov = item->movements1[i]; if (mov->_staticsObj1 == item->statics[st1idx]) { if (!item->movements2[i] && (!flop || mov->_field_50)) { @@ -2205,22 +2306,21 @@ int MGM::recalcOffsets(int idx, int st1idx, int st2idx, bool flip, bool flop) { int stidx = getStaticsIndex(idx, item->movements1[i]->_staticsObj2); int recalc = recalcOffsets(idx, stidx, st2idx, flip, flop); + int sz = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size(); + int newsz = sz + item->subItems[stidx + 6 * st2idx * _items[idx]->statics.size()]->field_C; if (recalc >= 0) { - if (!item->subItems[subIdx].movement || item->subItems[subIdx].field_8 > recalc + 1 || - (item->subItems[subIdx].field_8 == recalc + 1 && item->subItems[subIdx].field_C > v20) { - item->subItems[subIdx].movement = mov; - item->subItems[subIdx].staticsIndex = stidx; - item->subItems[subIdx].field_8 = recalc + 1; - - int sz = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size(); + if (!item->subItems[subIdx]->movement || item->subItems[subIdx]->field_8 > recalc + 1 || + (item->subItems[subIdx]->field_8 == recalc + 1 && item->subItems[subIdx]->field_C > newsz)) { + item->subItems[subIdx]->movement = mov; + item->subItems[subIdx]->staticsIndex = stidx; + item->subItems[subIdx]->field_8 = recalc + 1; + item->subItems[subIdx]->field_C = newsz; - item->subItems[subIdx].field_C = sz + item->subItems[stidx + 6 * st2idx * _items[idx].staticsListCount]->field_C; + mov->calcSomeXY(point, 0); - mov->calcSomeXY(&point, 0); - - item->subItems[subIdx].x = item->subItems[stidx + 6 * st2idx * _items[idx].staticsListCount]->x + point.x; - item->subItems[subIdx].y = item->subItems[stidx + 6 * st2idx * _items[idx].staticsListCount]->y + point.y; + item->subItems[subIdx]->x = item->subItems[stidx + 6 * st2idx * _items[idx]->statics.size()]->x + point.x; + item->subItems[subIdx]->y = item->subItems[stidx + 6 * st2idx * _items[idx]->statics.size()]->y + point.y; } } } @@ -2235,17 +2335,17 @@ int MGM::recalcOffsets(int idx, int st1idx, int st2idx, bool flip, bool flop) { if (recalc >= 0) { if (!item->subItems[subIdx]->movement || item->subItems[subIdx]->field_8 > recalc + 1) { item->subItems[subIdx]->movement = mov; - item->subItems[subIdx].staticsIndex = stidx; - item->subItems[subIdx].field_8 = recalc + 1; + item->subItems[subIdx]->staticsIndex = stidx; + item->subItems[subIdx]->field_8 = recalc + 1; int sz = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size(); - item->subItems[subIdx].field_C = sz + item->subItems[stidx + 6 * st2idx * _items[idx].staticsListCount]->field_C; + item->subItems[subIdx]->field_C = sz + item->subItems[stidx + 6 * st2idx * _items[idx]->statics.size()]->field_C; - mov->calcSomeXY(&point, 0); + mov->calcSomeXY(point, 0); - item->subItems[subIdx].x = item->subItems[stidx + 6 * st2idx * _items[idx].staticsListCount]->x - point.x; - item->subItems[subIdx].y = item->subItems[stidx + 6 * st2idx * _items[idx].staticsListCount]->y - point.y; + item->subItems[subIdx]->x = item->subItems[stidx + 6 * st2idx * _items[idx]->statics.size()]->x - point.x; + item->subItems[subIdx]->y = item->subItems[stidx + 6 * st2idx * _items[idx]->statics.size()]->y - point.y; } } } @@ -2257,10 +2357,26 @@ int MGM::recalcOffsets(int idx, int st1idx, int st2idx, bool flip, bool flop) { return item->subItems[subIdx]->field_8; return -1; -#endif - warning("STUB: MGM::recalcOffsets()"); +} - return 0; +int MGM::refreshOffsets(int objectId, int idx1, int idx2) { + int idx = getItemIndexById(objectId); + + if (idx != -1) { + int from = getStaticsIndexById(idx, idx1); + int to = getStaticsIndexById(idx, idx2); + + MGMSubItem *sub = _items[idx]->subItems[from + to * _items[idx]->statics.size()]; + + if (sub->movement) { + idx = sub->field_8; + } else { + clearMovements2(idx); + idx = recalcOffsets(idx, from, to, 0, 1); + } + } + + return idx; } Common::Point *MGM::calcLength(Common::Point *pRes, Movement *mov, int x, int y, int *mult, int *len, int flag) { diff --git a/engines/fullpipe/motion.h b/engines/fullpipe/motion.h index 96442cac51..4d92fd7fed 100644 --- a/engines/fullpipe/motion.h +++ b/engines/fullpipe/motion.h @@ -138,7 +138,7 @@ struct MGMItem { Common::Array<MGMSubItem *> subItems; Common::Array<Statics *> statics; Common::Array<Movement *> movements1; - Common::Array<Movement *> movements2; + Common::Array<int> movements2; MGMItem(); }; @@ -178,6 +178,9 @@ public: int recalcOffsets(int idx, int st1idx, int st2idx, bool flip, bool flop); Common::Point *calcLength(Common::Point *point, Movement *mov, int x, int y, int *mult, int *len, int flag); ExCommand2 *buildExCommand2(Movement *mov, int objId, int x1, int y1, Common::Point *x2, Common::Point *y2, int len); + MessageQueue *genMQ(StaticANIObject *ani, int staticsIndex, int staticsId, int *resStatId, Common::Point **pointArr); + int countPhases(int idx, int subIdx, int subOffset, int flag); + int refreshOffsets(int objectId, int idx1, int idx2); }; struct MctlLadderMovementVars { diff --git a/engines/fullpipe/scenes.cpp b/engines/fullpipe/scenes.cpp index 47c6a3c8cd..7420c1b1cf 100644 --- a/engines/fullpipe/scenes.cpp +++ b/engines/fullpipe/scenes.cpp @@ -1106,10 +1106,6 @@ int defaultUpdateCursor() { return g_fp->_cursorId; } -void FullpipeEngine::processArcade(ExCommand *ex) { - warning("STUB: FullpipeEngine::processArcade()"); -} - void FullpipeEngine::updateMapPiece(int mapId, int update) { for (int i = 0; i < 200; i++) { int hiWord = (_mapTable[i] >> 16) & 0xffff; diff --git a/engines/fullpipe/sound.cpp b/engines/fullpipe/sound.cpp index aa91f25087..3c13bad854 100644 --- a/engines/fullpipe/sound.cpp +++ b/engines/fullpipe/sound.cpp @@ -26,6 +26,7 @@ #include "fullpipe/scene.h" #include "fullpipe/sound.h" #include "fullpipe/ngiarchive.h" +#include "fullpipe/messages.h" #include "common/memstream.h" #include "audio/audiostream.h" #include "audio/decoders/vorbis.h" @@ -73,6 +74,18 @@ bool SoundList::loadFile(const char *fname, char *libname) { return load(archive, libname); } +Sound *SoundList::getSoundItemById(int id) { + if (_soundItemsCount == 0) { + return _soundItems[0]->getId() != id ? 0 : _soundItems[0]; + } + + for (int i = 0; i < _soundItemsCount; i++) { + if (_soundItems[i]->getId() == id) + return _soundItems[i]; + } + return NULL; +} + Sound::Sound() { _id = 0; _directSoundBuffer = 0; @@ -80,10 +93,13 @@ Sound::Sound() { _objectId = 0; memset(_directSoundBuffers, 0, sizeof(_directSoundBuffers)); _description = 0; + _volume = 100; } Sound::~Sound() { - warning("STUB: Sound::~Sound()"); + freeSound(); + + free(_description); } bool Sound::load(MfcArchive &file, NGIArchive *archive) { @@ -120,27 +136,156 @@ void Sound::setPanAndVolumeByStaticAni() { } void Sound::setPanAndVolume(int vol, int pan) { - warning("STUB: Sound::setPanAndVolume"); + g_fp->_mixer->setChannelVolume(_handle, vol / 39); // 0..10000 + g_fp->_mixer->setChannelBalance(_handle, pan / 78); // -10000..10000 +} + +void Sound::play(int flag) { + Audio::SoundHandle handle = getHandle(); + + if (g_fp->_mixer->isSoundHandleActive(handle)) + return; + + byte *soundData = loadData(); + Common::MemoryReadStream *dataStream = new Common::MemoryReadStream(soundData, getDataSize()); + Audio::RewindableAudioStream *wav = Audio::makeWAVStream(dataStream, DisposeAfterUse::YES); + Audio::AudioStream *audioStream = new Audio::LoopingAudioStream(wav, (flag == 1) ? 0 : 1); + + g_fp->_mixer->playStream(Audio::Mixer::kSFXSoundType, &handle, audioStream); +} + +void Sound::freeSound() { + stop(); + + free(_soundData); +} + +int Sound::getVolume() { + return g_fp->_mixer->getChannelVolume(_handle) * 39; // 0..10000 +} + +void Sound::stop() { + g_fp->_mixer->stopHandle(_handle); } -void FullpipeEngine::setSceneMusicParameters(GameVar *var) { +void FullpipeEngine::setSceneMusicParameters(GameVar *gvar) { warning("STUB: FullpipeEngine::setSceneMusicParameters()"); - // TODO: Finish this (MINDELAY, MAXDELAY, LOCAL, SEQUENCE, STARTDELAY etc) - stopAllSoundStreams(); +#if 0 + stopSoundStream2(); + + if (soundStream3) + FSOUND_Stream_Stop(soundStream4); +#endif + + if (_musicLocal) + stopAllSoundStreams(); + + GameVar *var = gvar->getSubVarByName("MUSIC"); + + memset(_sceneTracks, 0, sizeof(_sceneTracks)); + + _numSceneTracks = 0; + _sceneTrackHasSequence = false; + + if (!var) + return; + _musicGameVar = var; + + GameVar *tr = var->getSubVarByName("TRACKS"); + if (tr) { + GameVar *sub = tr->_subVars; + + while (sub) { + if (_musicAllowed & sub->_value.intValue) { + strcpy(_sceneTracks[_numSceneTracks], sub->_varName); + + _numSceneTracks++; + } + + sub = sub->_nextVarObj; + } + } + + _musicMinDelay = var->getSubVarAsInt("MINDELAY"); + _musicMaxDelay = var->getSubVarAsInt("MAXDELAY"); + _musicLocal = var->getSubVarAsInt("LOCAL"); + + GameVar *seq = var->getSubVarByName("SEQUENCE"); + + if (seq) { + _sceneTrackHasSequence = true; + + strcpy(_trackName, seq->_value.stringValue); + } + + if (_musicLocal) + stopAllSoundStreams(); + + if (!_sceneTrackIsPlaying || _musicLocal) + _trackStartDelay = var->getSubVarAsInt("STARTDELAY"); } void FullpipeEngine::startSceneTrack() { - // TODO: Finish this -#ifdef USE_VORBIS - if (g_fp->_mixer->isSoundHandleActive(_sceneTrackHandle)) - return; + if (!_sceneTrackIsPlaying && _numSceneTracks > 0) { + if (_trackStartDelay > 0) { + _trackStartDelay--; + } else { + int trackNum = getSceneTrack(); + + if (trackNum == -1) { + strcpy(_sceneTracksCurrentTrack, "silence"); + + _trackStartDelay = 2880; + _sceneTrackIsPlaying = 0; + } else { + strcpy(_sceneTracksCurrentTrack, _sceneTracks[trackNum]); + + startSoundStream1(_sceneTracksCurrentTrack); + + _sceneTrackIsPlaying = true; + } + } + } +} + +int FullpipeEngine::getSceneTrack() { + int res; + + if (_sceneTrackHasSequence) { + int num = _musicGameVar->getSubVarAsInt("TRACKS"); + + if (_trackName[num + 1] == 's') { // 'silence' + res = -1; + } else { + res = _trackName[num + 1] - '0'; + + if (res < 0 || res >= _numSceneTracks) + res = 0; + } - GameVar *musicTrackVar = _musicGameVar->getSubVarByName("MUSIC")->getSubVarByName("TRACKS")->_subVars; - if (!musicTrackVar) + int track = num + 1; + + if (!_trackName[num + 2]) + track = 0; + + _musicGameVar->setSubVarAsInt("TRACKS", track); + } else { + res = _numSceneTracks * (_updateTicks % 10) / 10; + } + + return res; +} + +void FullpipeEngine::startSoundStream1(char *trackName) { + warning("STUB: FullpipeEngine::startSoundStream1(%s)", trackName); + + stopAllSoundStreams(); + +#ifdef USE_VORBIS + if (_mixer->isSoundHandleActive(_sceneTrackHandle)) return; - char *trackName = musicTrackVar->_varName; Common::File *track = new Common::File(); if (!track->open(trackName)) { warning("Could not open %s", trackName); @@ -148,40 +293,130 @@ void FullpipeEngine::startSceneTrack() { return; } Audio::RewindableAudioStream *ogg = Audio::makeVorbisStream(track, DisposeAfterUse::YES); - g_fp->_mixer->playStream(Audio::Mixer::kMusicSoundType, &_sceneTrackHandle, ogg); + _mixer->playStream(Audio::Mixer::kMusicSoundType, &_sceneTrackHandle, ogg); #endif } void FullpipeEngine::stopAllSounds() { // TODO: Differences from stopAllSoundStreams() - g_fp->_mixer->stopAll(); + _mixer->stopAll(); } void FullpipeEngine::toggleMute() { - warning("STUB: FullpipeEngine::toggleMute()"); + if (_soundEnabled) { + _sfxVolume = _sfxVolume != -10000 ? -10000 : 0; + + updateSoundVolume(); + } } void FullpipeEngine::playSound(int id, int flag) { - SoundList *soundList = g_fp->_currentScene->_soundList; - Sound *sound = soundList->getSoundById(id); + Sound *sound = 0; + + for (int i = 0; i < _currSoundListCount; i++) { + sound = _currSoundList1[i]->getSoundItemById(id); + + if (sound) + break; + } + if (!sound) { warning("playSound: Can't find sound with ID %d", id); return; } - byte *soundData = sound->loadData(); - Common::MemoryReadStream *dataStream = new Common::MemoryReadStream(soundData, sound->getDataSize()); - Audio::RewindableAudioStream *wav = Audio::makeWAVStream(dataStream, DisposeAfterUse::YES); - Audio::AudioStream *audioStream = new Audio::LoopingAudioStream(wav, (flag == 1) ? 0 : 1); - Audio::SoundHandle handle = sound->getHandle(); - g_fp->_mixer->playStream(Audio::Mixer::kSFXSoundType, &handle, audioStream); + + sound->play(flag); } void FullpipeEngine::playTrack(GameVar *sceneVar, const char *name, bool delayed) { warning("STUB: FullpipeEngine::playTrack(var, %s, %d)", name, delayed); +#if 0 + stopSoundStream2(); + + if (soundStream3) + FSOUND_Stream_Stop(soundStream4); +#endif + + if (_musicLocal) + stopAllSoundStreams(); + + GameVar *var = sceneVar->getSubVarByName(name); + + memset(_sceneTracks, 0, sizeof(_sceneTracks)); + + _numSceneTracks = 0; + _sceneTrackHasSequence = false; + + if (!var) + return; + + _musicGameVar = var; + + GameVar *tr = var->getSubVarByName("TRACKS"); + if (tr) { + GameVar *sub = tr->_subVars; + + while (sub) { + if (_musicAllowed & sub->_value.intValue) { + strcpy(_sceneTracks[_numSceneTracks], sub->_varName); + + _numSceneTracks++; + } + + sub = sub->_nextVarObj; + } + } + + _musicMinDelay = var->getSubVarAsInt("MINDELAY"); + _musicMaxDelay = var->getSubVarAsInt("MAXDELAY"); + _musicLocal = var->getSubVarAsInt("LOCAL"); + + GameVar *seq = var->getSubVarByName("SEQUENCE"); + + if (seq) { + _sceneTrackHasSequence = true; + + strcpy(_trackName, seq->_value.stringValue); + } + + if (delayed) { + if (_sceneTrackIsPlaying && _numSceneTracks == 1) { + if (strcmp(_sceneTracksCurrentTrack, _sceneTracks[0])) + stopAllSoundStreams(); + } + + _trackStartDelay = var->getSubVarAsInt("STARTDELAY"); + } } void global_messageHandler_handleSound(ExCommand *cmd) { - debug(0, "STUB: global_messageHandler_handleSound()"); + if (!g_fp->_soundEnabled) + return; + + Sound *snd = 0; + + for (int i = 0; i < g_fp->_currSoundListCount; i++) + snd = g_fp->_currSoundList1[i]->getSoundItemById(cmd->_messageNum); + + if (!snd) + return; + + if (cmd->_field_14 & 1) { + if (!g_fp->_flgSoundList && (cmd->_field_14 & 4)) + snd->freeSound(); + + snd->updateVolume(); + + if (snd->_objectId && g_fp->_currentScene->getStaticANIObject1ById(snd->_objectId, -1)) + snd->setPanAndVolumeByStaticAni(); + else + snd->setPanAndVolume(g_fp->_sfxVolume, 0); + + if (snd->getVolume() > -3500) + snd->play(cmd->_keyCode); + } else if (cmd->_field_14 & 2) { + snd->stop(); + } } void FullpipeEngine::stopSoundStream2() { @@ -190,21 +425,23 @@ void FullpipeEngine::stopSoundStream2() { void FullpipeEngine::stopAllSoundStreams() { // TODO: Differences from stopAllSounds() - g_fp->_mixer->stopAll(); + _mixer->stopAll(); } void FullpipeEngine::stopAllSoundInstances(int id) { - SoundList *soundList = g_fp->_currentScene->_soundList; - for (int i = 0; i < soundList->getCount(); i++) { - Sound *sound = soundList->getSoundByIndex(i); - if (sound->getId() == id) { - g_fp->_mixer->stopHandle(sound->getHandle()); - } + for (int i = 0; i < _currSoundListCount; i++) { + Sound *sound = _currSoundList1[i]->getSoundItemById(id); + + if (sound) + sound->stop(); } } void FullpipeEngine::updateSoundVolume() { - debug(3, "STUB FullpipeEngine::updateSoundVolume()"); + for (int i = 0; i < _currSoundListCount; i++) + for (int j = 0; i < _currSoundList1[i]->getCount(); j++) { + _currSoundList1[i]->getSoundByIndex(j)->setPanAndVolume(_sfxVolume, 0); + } } void FullpipeEngine::setMusicVolume(int vol) { diff --git a/engines/fullpipe/sound.h b/engines/fullpipe/sound.h index e284e5efab..14e766f5bb 100644 --- a/engines/fullpipe/sound.h +++ b/engines/fullpipe/sound.h @@ -32,6 +32,7 @@ class Sound : public MemoryObject { int _directSoundBuffers[7]; byte *_soundData; Audio::SoundHandle _handle; + int _volume; public: int16 _objectId; @@ -46,6 +47,11 @@ public: int getId() const { return _id; } Audio::SoundHandle getHandle() const { return _handle; } + void play(int flag); + void freeSound(); + int getVolume(); + void stop(); + void setPanAndVolumeByStaticAni(); void setPanAndVolume(int vol, int pan); }; @@ -63,13 +69,7 @@ class SoundList : public CObject { int getCount() { return _soundItemsCount; } Sound *getSoundByIndex(int idx) { return _soundItems[idx]; } - Sound *getSoundById(int id) { - for (int i = 0; i < _soundItemsCount; i++) { - if (_soundItems[i]->getId() == id) - return _soundItems[i]; - } - return NULL; - } + Sound *getSoundItemById(int id); }; } // End of namespace Fullpipe diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp index a3a160b5b2..f1abac5778 100644 --- a/engines/fullpipe/statics.cpp +++ b/engines/fullpipe/statics.cpp @@ -277,8 +277,11 @@ void StaticANIObject::deleteFromGlobalMessageQueue() { } } -void StaticANIObject::queueMessageQueue(MessageQueue *mq) { - if (isIdle() && !(_flags & 0x80)) { +bool StaticANIObject::queueMessageQueue(MessageQueue *mq) { + if (_flags & 0x80) + return false; + + if (isIdle()) { deleteFromGlobalMessageQueue(); _messageQueueId = 0; _messageNum = 0; @@ -296,6 +299,8 @@ void StaticANIObject::queueMessageQueue(MessageQueue *mq) { _messageQueueId = 0; } } + + return true; } void StaticANIObject::restartMessageQueue(MessageQueue *mq) { @@ -1019,9 +1024,26 @@ void StaticANIObject::adjustSomeXY() { } MessageQueue *StaticANIObject::changeStatics1(int msgNum) { - warning("STUB: StaticANIObject::changeStatics1(%d)", msgNum); + g_fp->_mgm->addItem(_id); - return 0; + MessageQueue *mq = g_fp->_mgm->genMQ(this, msgNum, 0, 0, 0); + + if (!mq) + return 0; + + if (mq->getCount() <= 0) { + g_fp->_globalMessageQueueList->addMessageQueue(mq); + + if (_flags & 1) + _messageQueueId = mq->_id; + } else { + if (!queueMessageQueue(mq)) + return 0; + + g_fp->_globalMessageQueueList->addMessageQueue(mq); + } + + return mq; } void StaticANIObject::changeStatics2(int objId) { @@ -1347,6 +1369,31 @@ bool StaticANIObject::startAnim(int movementId, int messageQueueId, int dynPhase return true; } +Common::Point *StaticANIObject::calcStepLen(Common::Point *p) { + if (_movement) { + Common::Point point; + + _movement->calcSomeXY(point, 0); + + p->x = point.x; + p->y = point.y; + + int idx = _stepArray.getCurrPointIndex() - _movement->_currDynamicPhaseIndex - 1; + + if (idx >= 0) { + _stepArray.getPoint(&point, idx, _movement->_currDynamicPhaseIndex + 2); + + p->x += point.x; + p->y += point.y; + } + } else { + p->x = 0; + p->y = 0; + } + + return p; +} + Statics::Statics() { _staticsId = 0; _picture = 0; diff --git a/engines/fullpipe/statics.h b/engines/fullpipe/statics.h index 89703965cd..d678957163 100644 --- a/engines/fullpipe/statics.h +++ b/engines/fullpipe/statics.h @@ -217,7 +217,7 @@ public: void setAlpha(int alpha); void deleteFromGlobalMessageQueue(); - void queueMessageQueue(MessageQueue *msg); + bool queueMessageQueue(MessageQueue *msg); void restartMessageQueue(MessageQueue *msg); MessageQueue *getMessageQueue(); bool trySetMessageQueue(int msgNum, int qId); @@ -246,6 +246,7 @@ public: void draw2(); MovTable *countMovements(); + Common::Point *calcStepLen(Common::Point *p); void setSpeed(int speed); void updateStepPos(); |