diff options
Diffstat (limited to 'engines/fullpipe/modal.cpp')
-rw-r--r-- | engines/fullpipe/modal.cpp | 729 |
1 files changed, 725 insertions, 4 deletions
diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp index 603aaff026..459c714984 100644 --- a/engines/fullpipe/modal.cpp +++ b/engines/fullpipe/modal.cpp @@ -21,12 +21,13 @@ */ #include "fullpipe/fullpipe.h" -#include "fullpipe/modal.h" #include "fullpipe/messages.h" #include "fullpipe/constants.h" #include "fullpipe/motion.h" #include "fullpipe/scenes.h" #include "fullpipe/gameloader.h" +#include "fullpipe/statics.h" +#include "fullpipe/modal.h" #include "fullpipe/constants.h" @@ -718,7 +719,7 @@ bool ModalCredits::init(int counterdiff) { g_fp->_modalObject = menu; - menu->_field_34 = 1; + menu->_mfield_34 = 1; } return true; @@ -750,9 +751,513 @@ void ModalCredits::update() { } ModalMainMenu::ModalMainMenu() { - warning("STUB: ModalMainMenu::ModalMainMenu()"); + _areas.clear(); + + _lastArea = 0; + _hoverAreaId = 0; + _mfield_34 = 0; + _scene = g_fp->accessScene(SC_MAINMENU); + _debugKeyCount = 0; + _sliderOffset = 0; + _screct.left = g_fp->_sceneRect.left; + _screct.top = g_fp->_sceneRect.top; + _screct.right = g_fp->_sceneRect.right; + _screct.bottom = g_fp->_sceneRect.bottom; + + if (g_fp->_currentScene) { + _bgX = g_fp->_currentScene->_x; + _bgY = g_fp->_currentScene->_y; + } else { + _bgX = 0; + _bgY = 0; + } + + g_fp->_sceneRect.top = 0; + g_fp->_sceneRect.left = 0; + g_fp->_sceneRect.right = 800; + g_fp->_sceneRect.bottom = 600; + + MenuArea *area; + + area = new MenuArea(); + area->picIdL = PIC_MNU_EXIT_L; + area->picObjD = 0; + area->picObjL = _scene->getPictureObjectById(area->picIdL, 0); + area->picObjL->_flags &= 0xFFFB; + _areas.push_back(area); + + area = new MenuArea(); + area->picIdL = PIC_MNU_CONTINUE_L; + area->picObjD = 0; + area->picObjL = _scene->getPictureObjectById(area->picIdL, 0); + area->picObjL->_flags &= 0xFFFB; + _areas.push_back(area); + + if (isSaveAllowed()) { + area = new MenuArea(); + area->picIdL = PIC_MNU_SAVE_L; + area->picObjD = 0; + area->picObjL = _scene->getPictureObjectById(area->picIdL, 0); + area->picObjL->_flags &= 0xFFFB; + _areas.push_back(area); + } + + area = new MenuArea(); + area->picIdL = PIC_MNU_LOAD_L; + area->picObjD = 0; + area->picObjL = _scene->getPictureObjectById(area->picIdL, 0); + area->picObjL->_flags &= 0xFFFB; + _areas.push_back(area); + + area = new MenuArea(); + area->picIdL = PIC_MNU_RESTART_L; + area->picObjD = 0; + area->picObjL = _scene->getPictureObjectById(area->picIdL, 0); + area->picObjL->_flags &= 0xFFFB; + _areas.push_back(area); + + area = new MenuArea(); + area->picIdL = PIC_MNU_AUTHORS_L; + area->picObjD = 0; + area->picObjL = _scene->getPictureObjectById(area->picIdL, 0); + area->picObjL->_flags &= 0xFFFB; + _areas.push_back(area); + + area = new MenuArea(); + area->picIdL = PIC_MNU_SLIDER_L; + area->picObjD = _scene->getPictureObjectById(PIC_MNU_SLIDER_D, 0); + area->picObjD->_flags |= 4; + area->picObjL = _scene->getPictureObjectById(area->picIdL, 0); + area->picObjL->_flags &= 0xFFFB; + _areas.push_back(area); + _menuSliderIdx = _areas.size() - 1; + + area = new MenuArea(); + area->picIdL = PIC_MNU_MUSICSLIDER_L; + area->picObjD = _scene->getPictureObjectById(PIC_MNU_MUSICSLIDER_D, 0); + area->picObjD->_flags |= 4; + area->picObjL = _scene->getPictureObjectById(area->picIdL, 0); + area->picObjL->_flags &= 0xFFFB; + _areas.push_back(area); + _musicSliderIdx = _areas.size() - 1; + + if (g_fp->_mainMenu_debugEnabled) + enableDebugMenuButton(); + + setSliderPos(); +} - _field_34 = 0; +void ModalMainMenu::update() { + _scene->draw(); +} + +bool ModalMainMenu::handleMessage(ExCommand *message) { + if (message->_messageKind != 17) + return false; + + Common::Point point; + + if (message->_messageNum == 29) { + point.x = message->_x; + point.y = message->_y; + + int numarea = checkHover(point); + + if (numarea >= 0) { + if (numarea == _menuSliderIdx) { + _lastArea = _areas[_menuSliderIdx]; + _sliderOffset = _lastArea->picObjL->_ox - point.x; + + return false; + } + + if (numarea == _musicSliderIdx) { + _lastArea = _areas[_musicSliderIdx]; + _sliderOffset = _lastArea->picObjL->_ox - point.x; + + return false; + } + + _hoverAreaId = _areas[numarea]->picIdL; + } + + return false; + } + + if (message->_messageNum == 30) { + if (_lastArea) + _lastArea = 0; + + return false; + } + + if (message->_messageNum != 36) + return false; + + if (message->_keyCode == 27) + _hoverAreaId = PIC_MNU_CONTINUE_L; + else + enableDebugMenu(message->_keyCode); + + return false; +} + +bool ModalMainMenu::init(int counterdiff) { + switch (_hoverAreaId) { + case PIC_MNU_RESTART_L: + g_fp->restartGame(); + + if (this == g_fp->_modalObject) + return false; + + delete this; + break; + + case PIC_MNU_EXIT_L: + { + ModalQuery *mq = new ModalQuery(); + + g_fp->_modalObject = mq; + + mq->_parentObj = this; + mq->create(_scene, (PictureObject *)_scene->_picObjList[0], PIC_MEX_BGR); + + _hoverAreaId = 0; + + return true; + } + + case PIC_MNU_DEBUG_L: + g_fp->_gameLoader->unloadScene(SC_MAINMENU); + g_fp->_sceneRect = _screct; + + if (!g_fp->_currentScene) + error("ModalMainMenu::init: Bad state"); + + g_fp->_currentScene->_x = _bgX; + g_fp->_currentScene->_y = _bgY; + + g_fp->_gameLoader->preloadScene(g_fp->_currentScene->_sceneId, SC_DBGMENU); + + return false; + + case PIC_MNU_CONTINUE_L: + if (!_mfield_34) { + g_fp->_gameLoader->unloadScene(SC_MAINMENU); + g_fp->_sceneRect = _screct; + + if (g_fp->_currentScene) { + g_fp->_currentScene->_x = _bgX; + g_fp->_currentScene->_y = _bgY; + } + + return false; + } + + g_fp->restartGame(); + + if (this == g_fp->_modalObject) + return false; + + delete this; + break; + + case PIC_MNU_AUTHORS_L: + g_fp->_modalObject = new ModalCredits(); + g_fp->_modalObject->_parentObj = this; + + _hoverAreaId = 0; + + return true; + + case PIC_MNU_SAVE_L: + case PIC_MNU_LOAD_L: + { + ModalSaveGame *sg = new ModalSaveGame(); + + g_fp->_modalObject = sg; + g_fp->_modalObject->_parentObj = _parentObj; + + int mode = 0; + if (_hoverAreaId == PIC_MNU_SAVE_L) + mode = 1; + + sg->setup(g_fp->accessScene(SC_MAINMENU), mode); + sg->setScene(g_fp->accessScene(SC_MAINMENU)); + + sg->_rect = _screct; + sg->_oldBgX = _bgX; + sg->_oldBgY = _bgY; + + delete this; + } + + break; + + default: + if (_lastArea) { + updateSliderPos(); + } else { + g_fp->_cursorId = PIC_CSR_DEFAULT; + + int idx = checkHover(g_fp->_mouseScreenPos); + + if (idx < 0) + goto LABEL_40; + + g_fp->_cursorId = PIC_CSR_DEFAULT; + + if (idx != this->_menuSliderIdx && idx != this->_musicSliderIdx ) + goto LABEL_40; + } + + g_fp->_cursorId = PIC_CSR_LIFT; + + LABEL_40: + g_fp->setCursor(g_fp->_cursorId); + + updateVolume(); + + return true; + } + + return true; +} + +void ModalMainMenu::updateVolume() { + if (g_fp->_soundEnabled ) { + for (int s = 0; s < g_fp->_currSoundListCount; s++) + for (int i = 0; i < g_fp->_currSoundList1[s]->getCount(); i++) { + updateSoundVolume(g_fp->_currSoundList1[s]->getSoundByIndex(i)); + } + } +} + +void ModalMainMenu::updateSoundVolume(Sound *snd) { + if (!snd->_objectId) + return; + + StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(snd->_objectId, -1); + if (!ani) + return; + + int a, b; + + if (ani->_ox >= _screct.left) { + int par, pan; + + if (ani->_ox <= _screct.right) { + int dx; + + if (ani->_oy <= _screct.bottom) { + if (ani->_oy >= _screct.top) { + snd->setPanAndVolume(g_fp->_sfxVolume, 0); + + return; + } + dx = _screct.top - ani->_oy; + } else { + dx = ani->_oy - _screct.bottom; + } + + par = 0; + + if (dx > 800) { + snd->setPanAndVolume(-3500, 0); + return; + } + + pan = -3500; + a = g_fp->_sfxVolume - (-3500); + b = 800 - dx; + } else { + int dx = ani->_ox - _screct.right; + + if (dx > 800) { + snd->setPanAndVolume(-3500, 0); + return; + } + + pan = -3500; + par = dx * (-3500) / -800; + a = g_fp->_sfxVolume - (-3500); + b = 800 - dx; + } + + int32 pp = b * a; //(0x51EB851F * b * a) >> 32) >> 8; // TODO FIXME + + snd->setPanAndVolume(pan + (pp >> 31) + pp, 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); + + if (p > g_fp->_sfxVolume) + p = g_fp->_sfxVolume; + + snd->setPanAndVolume(p, dx * (-3500) / 800); + } else { + snd->setPanAndVolume(-3500, 0); + } + + warning("STUB: ModalMainMenu::updateSoundVolume()"); +} + +void ModalMainMenu::updateSliderPos() { + if (_lastArea->picIdL == PIC_MNU_SLIDER_L) { + int x = g_fp->_mouseScreenPos.x + _sliderOffset; + + if (x >= 65) { + if (x > 238) + x = 238; + } else { + x = 65; + } + + _lastArea->picObjD->setOXY(x, _lastArea->picObjD->_oy); + _lastArea->picObjL->setOXY(x, _lastArea->picObjD->_oy); + + int vol = 1000 * (3 * x - 195); + g_fp->_sfxVolume = vol / 173 - 3000; + + if (!(vol / 173)) + g_fp->_sfxVolume = -10000; + + g_fp->updateSoundVolume(); + } else if (_lastArea->picIdL == PIC_MNU_MUSICSLIDER_L) { + int x = g_fp->_mouseScreenPos.x + _sliderOffset; + + if (x >= 65) { + if (x > 238) + x = 238; + } else { + x = 65; + } + + _lastArea->picObjD->setOXY(x, _lastArea->picObjD->_oy); + _lastArea->picObjL->setOXY(x, _lastArea->picObjD->_oy); + + g_fp->setMusicVolume(255 * (x - 65) / 173); + } +} + +int ModalMainMenu::checkHover(Common::Point &point) { + for (uint i = 0; i < _areas.size(); i++) { + if (_areas[i]->picObjL->isPixelHitAtPos(point.x, point.y)) { + _areas[i]->picObjL->_flags |= 4; + + return i; + } else { + _areas[i]->picObjL->_flags &= 0xFFFB; + } + } + + if (isOverArea(_areas[_menuSliderIdx]->picObjL, &point)) { + _areas[_menuSliderIdx]->picObjL->_flags |= 4; + + return _menuSliderIdx; + } + + if (isOverArea(_areas[_musicSliderIdx]->picObjL, &point)) { + _areas[_musicSliderIdx]->picObjL->_flags |= 4; + + return _musicSliderIdx; + } + + return -1; +} + +bool ModalMainMenu::isOverArea(PictureObject *obj, Common::Point *point) { + Common::Point p; + + obj->getDimensions(&p); + + int left = point->x - 8; + int right = point->x + 12; + int down = point->y - 11; + int up = point->y + 9; + + if (left >= obj->_ox && right < obj->_ox + p.x && down >= obj->_oy && up < obj->_oy + p.y) + return true; + + return false; +} + +bool ModalMainMenu::isSaveAllowed() { + if (!g_fp->_isSaveAllowed) + return false; + + if (g_fp->_aniMan->_flags & 0x100) + return false; + + for (Common::Array<MessageQueue *>::iterator s = g_fp->_globalMessageQueueList->begin(); s != g_fp->_globalMessageQueueList->end(); ++s) { + if (!(*s)->_isFinished && ((*s)->getFlags() & 1)) + return false; + } + + return true; +} + +void ModalMainMenu::enableDebugMenu(char c) { + const char deb[] = "DEBUGER"; + + if (c == deb[_debugKeyCount]) { + _debugKeyCount++; + + if (deb[_debugKeyCount] ) + return; + + enableDebugMenuButton(); + } + + _debugKeyCount = 0; +} + +void ModalMainMenu::enableDebugMenuButton() { + MenuArea *area; + + for (uint i = 0; i < _areas.size(); i++) + if (_areas[i]->picIdL == PIC_MNU_DEBUG_L) + return; + + area = new MenuArea(); + area->picIdL = PIC_MNU_DEBUG_L; + area->picObjD = 0; + area->picObjL = _scene->getPictureObjectById(area->picIdL, 0); + area->picObjL->_flags &= 0xFFFB; + _areas.push_back(area); +} + +void ModalMainMenu::setSliderPos() { + int x = 173 * (g_fp->_sfxVolume + 3000) / 3000 + 65; + PictureObject *obj = _areas[_menuSliderIdx]->picObjD; + + if (x >= 65) { + if (x > 238) + x = 238; + } else { + x = 65; + } + + obj->setOXY(x, obj->_oy); + _areas[_menuSliderIdx]->picObjL->setOXY(x, obj->_oy); + + x = 173 * g_fp->_musicVolume / 255 + 65; + obj = _areas[_musicSliderIdx]->picObjD; + + if (x >= 65) { + if (x > 238) + x = 238; + } else { + x = 65; + } + + obj->setOXY(x, obj->_oy); + _areas[_musicSliderIdx]->picObjL->setOXY(x, obj->_oy); } ModalHelp::ModalHelp() { @@ -816,6 +1321,222 @@ void ModalHelp::launch() { } } +ModalQuery::ModalQuery() { + _picObjList = 0; + _bg = 0; + _okBtn = 0; + _cancelBtn = 0; + _queryResult = -1; +} + +ModalQuery::~ModalQuery() { + _bg->_flags &= 0xFFFB; + _cancelBtn->_flags &= 0xFFFB; + _okBtn->_flags &= 0xFFFB; +} + +bool ModalQuery::create(Scene *sc, PictureObject *picObjList, int id) { + if (id == PIC_MEX_BGR) { + _bg = sc->getPictureObjectById(PIC_MEX_BGR, 0); + + if (!_bg) + return false; + + _okBtn = sc->getPictureObjectById(PIC_MEX_OK, 0); + + if (!_okBtn) + return false; + + _cancelBtn = sc->getPictureObjectById(PIC_MEX_CANCEL, 0); + + if (!_cancelBtn) + return 0; + } else { + if (id != PIC_MOV_BGR) + return false; + + _bg = sc->getPictureObjectById(PIC_MOV_BGR, 0); + + if (!_bg) + return false; + + _okBtn = sc->getPictureObjectById(PIC_MOV_OK, 0); + + if (!_okBtn) + return false; + + _cancelBtn = sc->getPictureObjectById(PIC_MOV_CANCEL, 0); + + if (!_cancelBtn) + return false; + } + + _queryResult = -1; + _picObjList = picObjList; + + return true; +} + +void ModalQuery::update() { + if (_picObjList) + _picObjList->draw(); + + _bg->draw(); + + if (_okBtn->_flags & 4) + _okBtn->draw(); + + if (_cancelBtn->_flags & 4) + _cancelBtn->draw(); +} + +bool ModalQuery::handleMessage(ExCommand *cmd) { + if (cmd->_messageKind == 17) { + if (cmd->_messageNum == 29) { + if (_okBtn->isPointInside(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y)) { + _queryResult = 1; + + return false; + } + + if (_cancelBtn->isPointInside(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y)) + _queryResult = 0; + } else if (cmd->_messageNum == 36 && cmd->_keyCode == 27) { + _queryResult = 0; + + return false; + } + } + + return false; +} + +bool ModalQuery::init(int counterdiff) { + if (_okBtn->isPointInside(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y)) + _okBtn->_flags |= 4; + else + _okBtn->_flags &= 0xFFFB; + + if (_cancelBtn->isPointInside(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y)) + _cancelBtn->_flags |= 4; + else + _cancelBtn->_flags &= 0xFFFB; + + if (_queryResult == -1) { + return true; + } else { + if (_bg->_id == PIC_MEX_BGR) { + _cancelBtn->_flags &= 0xFFFB; + _okBtn->_flags &= 0xFFFB; + + if (_queryResult == 1) { + warning("STUB: ModalQuery::init()"); + //sceneFade(g_vrtDrawHandle, (Scene *)this->_picObjList, 0); + + //if (inputArFlag) { + // g_needRestart = 1; + // return 0; + //} + //SendMessageA(hwndCallback, WM_DESTROY, 0, 0); + } + } + } + + return false; +} + +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 < _filenames.size(); i++) + free(_filenames[i]); + + _filenames.clear(); +} + +void ModalSaveGame::setScene(Scene *sc) { + _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()"); +} + +char *ModalSaveGame::getSaveName() { + if (_queryRes < 0) + return 0; + + return _filenames[_queryRes]; +} + + void FullpipeEngine::openHelp() { if (!_modalObject) { ModalHelp *help = new ModalHelp; |