diff options
author | johndoe123 | 2015-11-24 00:10:10 +0100 |
---|---|---|
committer | Eugene Sandulenko | 2018-07-20 06:43:33 +0000 |
commit | fa17f684da1da7fded805746b75c454502ffe683 (patch) | |
tree | 1e668515abccf6455299a5b9fbadc2c5b6affd98 /engines/illusions/duckman | |
parent | 09bbb482a8ccdfb8e36128d40364900b99aa2a13 (diff) | |
download | scummvm-rg350-fa17f684da1da7fded805746b75c454502ffe683.tar.gz scummvm-rg350-fa17f684da1da7fded805746b75c454502ffe683.tar.bz2 scummvm-rg350-fa17f684da1da7fded805746b75c454502ffe683.zip |
ILLUSIONS: DUCKMAN: Start implementing the menu system
Still work-in-progress, missing functionality and buggy
Maybe needs some work for BBDOU where this isn't implemented yet.
Diffstat (limited to 'engines/illusions/duckman')
-rw-r--r-- | engines/illusions/duckman/illusions_duckman.cpp | 14 | ||||
-rw-r--r-- | engines/illusions/duckman/illusions_duckman.h | 2 | ||||
-rw-r--r-- | engines/illusions/duckman/menusystem_duckman.cpp | 179 | ||||
-rw-r--r-- | engines/illusions/duckman/menusystem_duckman.h | 70 | ||||
-rw-r--r-- | engines/illusions/duckman/scriptopcodes_duckman.cpp | 60 | ||||
-rw-r--r-- | engines/illusions/duckman/scriptopcodes_duckman.h | 6 |
6 files changed, 311 insertions, 20 deletions
diff --git a/engines/illusions/duckman/illusions_duckman.cpp b/engines/illusions/duckman/illusions_duckman.cpp index 7255327eaa..db8f83c295 100644 --- a/engines/illusions/duckman/illusions_duckman.cpp +++ b/engines/illusions/duckman/illusions_duckman.cpp @@ -23,6 +23,7 @@ #include "illusions/duckman/illusions_duckman.h" #include "illusions/duckman/duckman_dialog.h" #include "illusions/duckman/duckman_specialcode.h" +#include "illusions/duckman/menusystem_duckman.h" #include "illusions/duckman/scriptopcodes_duckman.h" #include "illusions/actor.h" #include "illusions/camera.h" @@ -110,6 +111,7 @@ Common::Error IllusionsEngine_Duckman::run() { _threads = new ThreadList(this); _updateFunctions = new UpdateFunctions(); _soundMan = new SoundMan(this); + _menuSystem = new DuckmanMenuSystem(this); _fader = new Fader(); @@ -180,6 +182,7 @@ Common::Error IllusionsEngine_Duckman::run() { delete _fader; + delete _menuSystem; delete _soundMan; delete _updateFunctions; delete _threads; @@ -231,8 +234,10 @@ void IllusionsEngine_Duckman::initInput() { _input->setInputEvent(kEventDown, 0x80) .addMouseButton(MOUSE_RIGHT_BUTTON) .addKey(Common::KEYCODE_DOWN); + /* Not implemented, used for original debugging purposes _input->setInputEvent(kEventF1, 0x100) .addKey(Common::KEYCODE_F1); + */ } #define UPDATEFUNCTION(priority, sceneId, callback) \ @@ -256,8 +261,13 @@ int IllusionsEngine_Duckman::updateScript(uint flags) { if (_screen->isDisplayOn() && !_screen->isFaderActive() && _pauseCtr == 0) { if (_input->pollEvent(kEventAbort)) { startScriptThread(0x00020342, 0); + //testMenu(this);//TODO DEBUG + + //BaseMenu *me = _menuSystem->getMenuById(kDuckmanPauseMenu); + //_menuSystem->openMenu(me); + //_menuSystem->runMenu(0x180002); + } else if (_input->pollEvent(kEventF1)) { - debug("F1"); startScriptThread(0x0002033F, 0); } } @@ -632,7 +642,7 @@ void IllusionsEngine_Duckman::cursorControlRoutine(Control *control, uint32 delt _dialogSys->updateDialogState(); break; case 4: - // TODO ShellMgr_update(_cursor._control); + _menuSystem->update(_cursor._control); break; } } diff --git a/engines/illusions/duckman/illusions_duckman.h b/engines/illusions/duckman/illusions_duckman.h index 39c421dae9..e2b3223efc 100644 --- a/engines/illusions/duckman/illusions_duckman.h +++ b/engines/illusions/duckman/illusions_duckman.h @@ -32,6 +32,7 @@ namespace Illusions { class Dictionary; class ScriptStack; class DuckmanDialogSystem; +class DuckmanMenuSystem; struct Cursor_Duckman { int _gameState; @@ -99,6 +100,7 @@ public: int _savedInventoryActorIndex; ScreenShaker *_screenShaker; + DuckmanMenuSystem *_menuSystem; void initInput(); diff --git a/engines/illusions/duckman/menusystem_duckman.cpp b/engines/illusions/duckman/menusystem_duckman.cpp new file mode 100644 index 0000000000..96d350ab4b --- /dev/null +++ b/engines/illusions/duckman/menusystem_duckman.cpp @@ -0,0 +1,179 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "illusions/illusions.h" +#include "illusions/actor.h" +#include "illusions/duckman/illusions_duckman.h" +#include "illusions/duckman/menusystem_duckman.h" + +namespace Illusions { + +// DuckmanMenuSystem + +DuckmanMenuSystem::DuckmanMenuSystem(IllusionsEngine_Duckman *vm) + : BaseMenuSystem(vm), _vm(vm) { + clearMenus(); +} + +DuckmanMenuSystem::~DuckmanMenuSystem() { + freeMenus(); +} + +void DuckmanMenuSystem::runMenu(MenuChoiceOffsets menuChoiceOffsets, int16 *menuChoiceOffset, + uint32 menuId, uint32 duration, uint timeOutMenuChoiceIndex, uint32 menuCallerThreadId) { + + setTimeOutDuration(duration, timeOutMenuChoiceIndex); + setMenuCallerThreadId(menuCallerThreadId); + setMenuChoiceOffsets(menuChoiceOffsets, menuChoiceOffset); + + int rootMenuId = convertRootMenuId(menuId | 0x180000); + BaseMenu *rootMenu = getMenuById(rootMenuId); + openMenu(rootMenu); + +} + +void DuckmanMenuSystem::clearMenus() { + for (int i = 0; i < kDuckmanLastMenuIndex; ++i) + _menus[i] = 0; +} + +void DuckmanMenuSystem::freeMenus() { + for (int i = 0; i < kDuckmanLastMenuIndex; ++i) + delete _menus[i]; +} + +BaseMenu *DuckmanMenuSystem::getMenuById(int menuId) { + if (!_menus[menuId]) + _menus[menuId] = createMenuById(menuId); + return _menus[menuId]; +} + +BaseMenu *DuckmanMenuSystem::createMenuById(int menuId) { + switch (menuId) { + case kDuckmanMainMenu: + return createMainMenu(); + case kDuckmanPauseMenu: + return createPauseMenu(); + case kDuckmanQueryRestartMenu: + return createQueryRestartMenu(); + case kDuckmanQueryQuitMenu: + return createQueryQuitMenu(); + default: + error("DuckmanMenuSystem::createMenuById() Invalid menu id %d", menuId); + } +} + +BaseMenu *DuckmanMenuSystem::createMainMenu() { + BaseMenu *menu = new BaseMenu(this, 0x00120003, 12, 17, 11, 27, 0); + menu->addMenuItem(new MenuItem("Start New Game", new MenuActionReturnChoice(this, 11))); + + menu->addMenuItem(new MenuItem("Load Saved Game", new MenuActionReturnChoice(this, 0))); + menu->addMenuItem(new MenuItem("Options", new MenuActionReturnChoice(this, 0))); + + // TODO menu->addMenuItem(new MenuItem("Load Saved Game", new MenuActionEnterMenu(this, kDuckmanLoadGameMenu))); + // TODO menu->addMenuItem(new MenuItem("Options", new MenuActionEnterMenu(this, kDuckmanOptionsMenu))); + menu->addMenuItem(new MenuItem("Quit Game", new MenuActionEnterQueryMenu(this, kDuckmanQueryQuitMenu, 12))); + return menu; +} + +BaseMenu *DuckmanMenuSystem::createLoadGameMenu() { + return 0; // TODO +} + +BaseMenu *DuckmanMenuSystem::createOptionsMenu() { + return 0; // TODO +} + +BaseMenu *DuckmanMenuSystem::createPauseMenu() { + BaseMenu *menu = new BaseMenu(this, 0x00120003, 12, 17, 11, 27, 1); + menu->addText(" Game Paused"); + menu->addText("-------------------"); + menu->addMenuItem(new MenuItem("Resume", new MenuActionReturnChoice(this, 1))); + //menu->addMenuItem(new MenuItem("Restart Game", new MenuActionEnterQueryMenu(this, kDuckmanQueryRestartMenu, 2))); + // TODO menu->addMenuItem(new MenuItem("Options", new MenuActionEnterMenu(this, kDuckmanOptionsMenu))); + menu->addMenuItem(new MenuItem("Quit Game", new MenuActionEnterQueryMenu(this, kDuckmanQueryQuitMenu, 3))); + return menu; +} + +BaseMenu *DuckmanMenuSystem::createQueryRestartMenu() { + return 0; // TODO +} + +BaseMenu *DuckmanMenuSystem::createQueryQuitMenu() { + BaseMenu *menu = new BaseMenu(this, 0x00120003, 12, 17, 11, 27, 2); + menu->addText("Do you really want to quit?"); + menu->addText("-------------------------------"); + menu->addMenuItem(new MenuItem("Yes, I'm outta here", new MenuActionReturnChoice(this, getQueryConfirmationChoiceIndex()))); + menu->addMenuItem(new MenuItem("No, just kidding", new MenuActionLeaveMenu(this))); + return menu; +} + +int DuckmanMenuSystem::convertRootMenuId(uint32 menuId) { + switch (menuId) { + case 0x180001: + return kDuckmanMainMenu; + case 0x180002: + return kDuckmanPauseMenu; + /* Debug menus, not implemented + case 0x180005: + case 0x180006: + case 0x180007: + */ + /* TODO CHECKME Another pause menu? + case 0x180008: + menuData = &g_menuDataPause; + */ + default: + error("DuckmanMenuSystem() Menu ID %08X not found", menuId); + } +} + +bool DuckmanMenuSystem::initMenuCursor() { + bool cursorInitialVisibleFlag = false; + Control *cursorControl = _vm->getObjectControl(0x40004); + if (cursorControl) { + if (cursorControl->_flags & 1) + cursorInitialVisibleFlag = false; + cursorControl->appearActor(); + } else { + Common::Point pos = _vm->getNamedPointPosition(0x70001); + _vm->_controls->placeActor(0x50001, pos, 0x60001, 0x40004, 0); + cursorControl = _vm->getObjectControl(0x40004); + } + return cursorInitialVisibleFlag; +} + +int DuckmanMenuSystem::getGameState() { + return _vm->_cursor._gameState; +} + +void DuckmanMenuSystem::setMenuCursorNum(int cursorNum) { + Control *mouseCursor = _vm->getObjectControl(0x40004); + _vm->setCursorActorIndex(5, cursorNum, 0); + mouseCursor->startSequenceActor(0x60001, 2, 0); +} + +void DuckmanMenuSystem::setGameState(int gameState) { + _vm->_cursor._gameState = gameState; +} + +} // End of namespace Illusions diff --git a/engines/illusions/duckman/menusystem_duckman.h b/engines/illusions/duckman/menusystem_duckman.h new file mode 100644 index 0000000000..bb43619acd --- /dev/null +++ b/engines/illusions/duckman/menusystem_duckman.h @@ -0,0 +1,70 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef ILLUSIONS_DUCKMAN_MENUSYSTEM_DUCKMAN_H +#define ILLUSIONS_DUCKMAN_MENUSYSTEM_DUCKMAN_H + +#include "illusions/menusystem.h" + +namespace Illusions { + +enum { + kDuckmanMainMenu, + kDuckmanLoadGameMenu, + kDuckmanOptionsMenu, + kDuckmanPauseMenu, + kDuckmanQueryQuitMenu, + kDuckmanQueryRestartMenu, + kDuckmanLastMenuIndex +}; + +class IllusionsEngine_Duckman; + +class DuckmanMenuSystem : public BaseMenuSystem { +public: + DuckmanMenuSystem(IllusionsEngine_Duckman *vm); + ~DuckmanMenuSystem(); + void runMenu(MenuChoiceOffsets menuChoiceOffsets, int16 *menuChoiceOffset, + uint32 menuId, uint32 duration, uint timeOutMenuChoiceIndex, uint32 menuCallerThreadId); +public://protected: + IllusionsEngine_Duckman *_vm; + BaseMenu *_menus[kDuckmanLastMenuIndex]; + void clearMenus(); + void freeMenus(); + BaseMenu *getMenuById(int menuId); + BaseMenu *createMenuById(int menuId); + BaseMenu *createMainMenu(); + BaseMenu *createLoadGameMenu(); + BaseMenu *createOptionsMenu(); + BaseMenu *createPauseMenu(); + BaseMenu *createQueryRestartMenu(); + BaseMenu *createQueryQuitMenu(); + int convertRootMenuId(uint32 menuId); + virtual bool initMenuCursor(); + virtual int getGameState(); + virtual void setGameState(int gameState); + virtual void setMenuCursorNum(int cursorNum); +}; + +} // End of namespace Illusions + +#endif // ILLUSIONS_DUCKMAN_MENUSYSTEM_DUCKMAN_H diff --git a/engines/illusions/duckman/scriptopcodes_duckman.cpp b/engines/illusions/duckman/scriptopcodes_duckman.cpp index 401f2e3eed..0fa7361574 100644 --- a/engines/illusions/duckman/scriptopcodes_duckman.cpp +++ b/engines/illusions/duckman/scriptopcodes_duckman.cpp @@ -23,10 +23,12 @@ #include "illusions/duckman/illusions_duckman.h" #include "illusions/duckman/scriptopcodes_duckman.h" #include "illusions/duckman/duckman_dialog.h" +#include "illusions/duckman/menusystem_duckman.h" #include "illusions/actor.h" #include "illusions/camera.h" #include "illusions/dictionary.h" #include "illusions/input.h" +#include "illusions/menusystem.h" #include "illusions/resources/scriptresource.h" #include "illusions/resources/talkresource.h" #include "illusions/screen.h" @@ -57,6 +59,7 @@ void ScriptOpcodes_Duckman::initOpcodes() { // First clear everything for (uint i = 0; i < 256; ++i) _opcodes[i] = 0; + // Register opcodes OPCODE(1, opNop); OPCODE(2, opSuspend); OPCODE(3, opYield); @@ -69,13 +72,15 @@ void ScriptOpcodes_Duckman::initOpcodes() { OPCODE(16, opLoadResource); OPCODE(17, opUnloadResource); OPCODE(18, opEnterScene18); + OPCODE(19, opUnloadResourcesBySceneId); OPCODE(20, opChangeScene); OPCODE(22, opStartModalScene); OPCODE(23, opExitModalScene); OPCODE(24, opEnterScene24); OPCODE(25, opLeaveScene24); - OPCODE(26, opEnterScene26); - OPCODE(27, opLeaveScene26); + OPCODE(26, opEnterDebugger); + OPCODE(27, opLeaveDebugger); + OPCODE(28, opDumpCurrentSceneFiles); OPCODE(32, opPanCenterObject); OPCODE(33, opPanTrackObject); OPCODE(34, opPanToObject); @@ -135,7 +140,6 @@ void ScriptOpcodes_Duckman::initOpcodes() { OPCODE(126, opDebug126); OPCODE(127, opDebug127); #if 0 - // Register opcodes OPCODE(8, opStartTempScriptThread); OPCODE(14, opSetThreadSceneId); OPCODE(15, opEndTalkThreads); @@ -252,6 +256,12 @@ void ScriptOpcodes_Duckman::opEnterScene18(ScriptThread *scriptThread, OpCall &o _vm->enterScene(sceneId, 0); } +void ScriptOpcodes_Duckman::opUnloadResourcesBySceneId(ScriptThread *scriptThread, OpCall &opCall) { + ARG_SKIP(2); + ARG_UINT32(sceneId); + _vm->_resSys->unloadResourcesBySceneId(sceneId); +} + //static uint dsceneId = 0, dthreadId = 0; //static uint dsceneId = 0x00010008, dthreadId = 0x00020029;//Beginning in Jac static uint dsceneId = 0x0001000A, dthreadId = 0x00020043;//Home front @@ -279,11 +289,13 @@ void ScriptOpcodes_Duckman::opChangeScene(ScriptThread *scriptThread, OpCall &op debug(1, "changeScene(%08X, %08X)", sceneId, threadId); //DEBUG + /* if (dsceneId) { sceneId = dsceneId; threadId = dthreadId; dsceneId = 0; } + */ if (_vm->_scriptResource->_properties.get(31)) { _vm->changeScene(0x10002, 0x20001, opCall._callerThreadId); @@ -331,12 +343,19 @@ void ScriptOpcodes_Duckman::opLeaveScene24(ScriptThread *scriptThread, OpCall &o _vm->leavePause(_vm->getCurrentScene(), opCall._callerThreadId); } -void ScriptOpcodes_Duckman::opEnterScene26(ScriptThread *scriptThread, OpCall &opCall) { - // TODO +void ScriptOpcodes_Duckman::opEnterDebugger(ScriptThread *scriptThread, OpCall &opCall) { + // Used for debugging purposes in the original engine + // This is not supported and only reachable by code not implemented here! + error("ScriptOpcodes_Duckman::opEnterDebugger() Debugger function called"); +} + +void ScriptOpcodes_Duckman::opLeaveDebugger(ScriptThread *scriptThread, OpCall &opCall) { + // See opEnterDebugger + error("ScriptOpcodes_Duckman::opLeaveDebugger() Debugger function called"); } -void ScriptOpcodes_Duckman::opLeaveScene26(ScriptThread *scriptThread, OpCall &opCall) { - // TODO +void ScriptOpcodes_Duckman::opDumpCurrentSceneFiles(ScriptThread *scriptThread, OpCall &opCall) { + _vm->dumpCurrSceneFiles(_vm->getCurrentScene(), opCall._callerThreadId); } void ScriptOpcodes_Duckman::opPanCenterObject(ScriptThread *scriptThread, OpCall &opCall) { @@ -615,23 +634,32 @@ void ScriptOpcodes_Duckman::opAddMenuChoice(ScriptThread *scriptThread, OpCall & } void ScriptOpcodes_Duckman::opDisplayMenu(ScriptThread *scriptThread, OpCall &opCall) { - ARG_INT16(unk1); + ARG_INT16(timeOutDuration); ARG_UINT32(menuId); - ARG_UINT32(unk2); - // TODO _vm->_shellMgr->displayMenu(_vm->_stack->topPtr(), &_vm->_menuChoiceOfs, menuId, unk1, unk2, opCall._callerThreadId); - // Remove menu choices from the stack + ARG_UINT32(timeOutMenuChoiceIndex); + + debug("timeOutMenuChoiceIndex: %d", timeOutMenuChoiceIndex); + + MenuChoiceOffsets menuChoiceOffsets; + + // Load menu choices from the stack do { - _vm->_stack->pop(); + int16 choiceOffs = _vm->_stack->pop(); + debug("choiceOffs: %04X", choiceOffs); + menuChoiceOffsets.push_back(choiceOffs); } while (_vm->_stack->pop() == 0); - + + _vm->_menuSystem->runMenu(menuChoiceOffsets, &_vm->_menuChoiceOfs, + menuId, timeOutDuration, timeOutMenuChoiceIndex, + opCall._threadId); + //DEBUG Resume calling thread, later done by the video player - _vm->notifyThreadId(opCall._callerThreadId); + //_vm->notifyThreadId(opCall._callerThreadId); } void ScriptOpcodes_Duckman::opSwitchMenuChoice(ScriptThread *scriptThread, OpCall &opCall) { -_vm->_menuChoiceOfs = 156; // DEBUG Chose "Start game" - + //_vm->_menuChoiceOfs = 156; // DEBUG Chose "Start game" opCall._deltaOfs += _vm->_menuChoiceOfs; } diff --git a/engines/illusions/duckman/scriptopcodes_duckman.h b/engines/illusions/duckman/scriptopcodes_duckman.h index 5b2f089460..d50f967a43 100644 --- a/engines/illusions/duckman/scriptopcodes_duckman.h +++ b/engines/illusions/duckman/scriptopcodes_duckman.h @@ -54,13 +54,15 @@ protected: void opUnloadResource(ScriptThread *scriptThread, OpCall &opCall); void opStartTimerThread(ScriptThread *scriptThread, OpCall &opCall); void opEnterScene18(ScriptThread *scriptThread, OpCall &opCall); + void opUnloadResourcesBySceneId(ScriptThread *scriptThread, OpCall &opCall); void opChangeScene(ScriptThread *scriptThread, OpCall &opCall); void opStartModalScene(ScriptThread *scriptThread, OpCall &opCall); void opExitModalScene(ScriptThread *scriptThread, OpCall &opCall); void opEnterScene24(ScriptThread *scriptThread, OpCall &opCall); void opLeaveScene24(ScriptThread *scriptThread, OpCall &opCall); - void opEnterScene26(ScriptThread *scriptThread, OpCall &opCall); - void opLeaveScene26(ScriptThread *scriptThread, OpCall &opCall); + void opEnterDebugger(ScriptThread *scriptThread, OpCall &opCall); + void opLeaveDebugger(ScriptThread *scriptThread, OpCall &opCall); + void opDumpCurrentSceneFiles(ScriptThread *scriptThread, OpCall &opCall); void opPanCenterObject(ScriptThread *scriptThread, OpCall &opCall); void opPanTrackObject(ScriptThread *scriptThread, OpCall &opCall); void opPanToObject(ScriptThread *scriptThread, OpCall &opCall); |