diff options
Diffstat (limited to 'engines/tsage/ringworld2/ringworld2_logic.cpp')
-rw-r--r-- | engines/tsage/ringworld2/ringworld2_logic.cpp | 757 |
1 files changed, 757 insertions, 0 deletions
diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp new file mode 100644 index 0000000000..e2583a5f1f --- /dev/null +++ b/engines/tsage/ringworld2/ringworld2_logic.cpp @@ -0,0 +1,757 @@ +/* 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 "common/config-manager.h" +#include "tsage/scenes.h" +#include "tsage/tsage.h" +#include "tsage/staticres.h" +#include "tsage/ringworld2/ringworld2_logic.h" +#include "tsage/ringworld2/ringworld2_scenes0.h" + +namespace TsAGE { + +namespace Ringworld2 { + +Scene *Ringworld2Game::createScene(int sceneNumber) { + switch (sceneNumber) { + /* Scene group #0 */ + // Quinn's room + case 100: return new Scene100(); + + default: + error("Unknown scene number - %d", sceneNumber); + break; + } +} + +/** + * Returns true if it is currently okay to restore a game + */ +bool Ringworld2Game::canLoadGameStateCurrently() { + return true; +} + +/** + * Returns true if it is currently okay to save the game + */ +bool Ringworld2Game::canSaveGameStateCurrently() { + return true; +} + +/*--------------------------------------------------------------------------*/ + +SceneExt::SceneExt(): Scene() { + _stripManager._onBegin = SceneExt::startStrip; + _stripManager._onEnd = SceneExt::endStrip; + + _field372 = _field37A = 0; + _savedPlayerEnabled = false; + _savedUiEnabled = false; + _savedCanWalk = false; + _focusObject = NULL; +} + +void SceneExt::postInit(SceneObjectList *OwnerList) { + Scene::postInit(OwnerList); +} + +void SceneExt::remove() { +/* + R2_GLOBALS._uiElements.hide(); + R2_GLOBALS._uiElements.resetClear(); + + if (_action) { + if (_action->_endHandler) + _action->_endHandler = NULL; + _action->remove(); + } + + _focusObject = NULL; +*/ +} + +void SceneExt::process(Event &event) { + if (!event.handled) + Scene::process(event); +} + +void SceneExt::dispatch() { +/* + _timerList.dispatch(); + + if (_field37A) { + if ((--_field37A == 0) && R2_GLOBALS._dayNumber) { + if (R2_GLOBALS._uiElements._active && R2_GLOBALS._player._enabled) { + R2_GLOBALS._uiElements.show(); + } + + _field37A = 0; + } + } +*/ + Scene::dispatch(); +} + +void SceneExt::loadScene(int sceneNum) { + Scene::loadScene(sceneNum); + + _v51C34.top = 0; + _v51C34.bottom = 300; +} + +bool SceneExt::display(CursorType action) { + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(9000, R2_GLOBALS._randomSource.getRandomNumber(2)); + break; + case CURSOR_USE: + SceneItem::display2(9000, R2_GLOBALS._randomSource.getRandomNumber(2) + 6); + break; + case CURSOR_TALK: + SceneItem::display2(9000, R2_GLOBALS._randomSource.getRandomNumber(2) + 3); + break; + default: + return false; + } + + return true; +} + +void SceneExt::fadeOut() { + uint32 black = 0; + R2_GLOBALS._scenePalette.fade((const byte *)&black, false, 100); +} + +void SceneExt::startStrip() { + SceneExt *scene = (SceneExt *)R2_GLOBALS._sceneManager._scene; + scene->_field372 = 1; + scene->_savedPlayerEnabled = R2_GLOBALS._player._enabled; + + if (scene->_savedPlayerEnabled) { + scene->_savedUiEnabled = R2_GLOBALS._player._uiEnabled; + scene->_savedCanWalk = R2_GLOBALS._player._canWalk; + R2_GLOBALS._player.disableControl(); +/* + if (!R2_GLOBALS._v50696 && R2_GLOBALS._uiElements._active) + R2_GLOBALS._uiElements.hide(); +*/ + } +} + +void SceneExt::endStrip() { + SceneExt *scene = (SceneExt *)R2_GLOBALS._sceneManager._scene; + scene->_field372 = 0; + + if (scene->_savedPlayerEnabled) { + R2_GLOBALS._player.enableControl(); + R2_GLOBALS._player._uiEnabled = scene->_savedUiEnabled; + R2_GLOBALS._player._canWalk = scene->_savedCanWalk; +/* + if (!R2_GLOBALS._v50696 && R2_GLOBALS._uiElements._active) + R2_GLOBALS._uiElements.show(); +*/ + } +} + +void SceneExt::clearScreen() { + R2_GLOBALS._screenSurface.fillRect(R2_GLOBALS._screenSurface.getBounds(), 0); +} + +void SceneExt::refreshBackground(int xAmount, int yAmount) { + switch (_activeScreenNumber) { + case 700: + case 1020: + case 1100: + case 1700: + case 2600: + case 2950: + case 3100: + case 3101: + case 3275: + case 3600: + // Use traditional style sectioned screen loading + Scene::refreshBackground(xAmount, yAmount); + return; + default: + // Break out to new style screen loading + break; + } + + /* New style background loading */ + + // Get the screen data + byte *dataP = g_resourceManager->getResource(RT18, _activeScreenNumber, 0); + int screenSize = g_vm->_memoryManager.getSize(dataP); + + // Lock the background for update + Graphics::Surface s = _backSurface.lockSurface(); + assert(screenSize == (s.w * s.h)); + + // Copy the data + byte *destP = (byte *)s.getBasePtr(0, 0); + Common::copy(dataP, dataP + (s.w * s.h), destP); + _backSurface.unlockSurface(); + + // Free the resource data + DEALLOCATE(dataP); +} + +/*--------------------------------------------------------------------------*/ + +DisplayHotspot::DisplayHotspot(int regionId, ...) { + _sceneRegionId = regionId; + + // Load up the actions + va_list va; + va_start(va, regionId); + + int param = va_arg(va, int); + while (param != LIST_END) { + _actions.push_back(param); + param = va_arg(va, int); + } + + va_end(va); +} + +bool DisplayHotspot::performAction(int action) { + for (uint i = 0; i < _actions.size(); i += 3) { + if (_actions[i] == action) { + display(_actions[i + 1], _actions[i + 2], SET_WIDTH, 200, SET_EXT_BGCOLOR, 7, LIST_END); + return true; + } + } + + return false; +} + +/*--------------------------------------------------------------------------*/ + +DisplayObject::DisplayObject(int firstAction, ...) { + // Load up the actions + va_list va; + va_start(va, firstAction); + + int param = firstAction; + while (param != LIST_END) { + _actions.push_back(param); + param = va_arg(va, int); + } + + va_end(va); +} + +bool DisplayObject::performAction(int action) { + for (uint i = 0; i < _actions.size(); i += 3) { + if (_actions[i] == action) { + display(_actions[i + 1], _actions[i + 2], SET_WIDTH, 200, SET_EXT_BGCOLOR, 7, LIST_END); + return true; + } + } + + return false; +} + +/*--------------------------------------------------------------------------*/ + +Ringworld2InvObjectList::Ringworld2InvObjectList(): + _inv1(1, 2), + _inv2(1, 3), + _inv3(1, 4), + _steppingDisks(1, 5), + _inv5(1, 6), + _inv6(1, 7), + _inv7(1, 8), + _inv8(1, 9), + _inv9(1, 10), + _inv10(1, 11), + _inv11(1, 12), + _inv12(1, 13), + _inv13(1, 14), + _inv14(1, 15), + _inv15(1, 16), + _inv16(1, 17), + _inv17(2, 2), + _inv18(2, 3), + _inv19(2, 4), + _inv20(2, 5), + _inv21(2, 5), + _inv22(2, 6), + _inv23(2, 7), + _inv24(2, 8), + _inv25(2, 9), + _inv26(2, 10), + _inv27(2, 11), + _inv28(2, 12), + _inv29(2, 13), + _inv30(2, 14), + _inv31(2, 15), + _inv32(2, 16), + _inv33(3, 2), + _inv34(3, 3), + _inv35(3, 4), + _inv36(3, 5), + _inv37(3, 6), + _inv38(3, 7), + _inv39(1, 10), + _inv40(3, 8), + _inv41(3, 9), + _inv42(3, 10), + _inv43(3, 11), + _inv44(3, 12), + _inv45(3, 13), + _inv46(3, 17), + _inv47(3, 14), + _inv48(3, 14), + _inv49(3, 15), + _inv50(3, 15), + _inv51(3, 17), + _inv52(4, 2) { + + // Add the items to the list + _itemList.push_back(&_inv1); + _itemList.push_back(&_inv2); + _itemList.push_back(&_inv3); + _itemList.push_back(&_steppingDisks); + _itemList.push_back(&_inv5); + _itemList.push_back(&_inv6); + _itemList.push_back(&_inv7); + _itemList.push_back(&_inv8); + _itemList.push_back(&_inv9); + _itemList.push_back(&_inv10); + _itemList.push_back(&_inv11); + _itemList.push_back(&_inv12); + _itemList.push_back(&_inv13); + _itemList.push_back(&_inv14); + _itemList.push_back(&_inv15); + _itemList.push_back(&_inv16); + _itemList.push_back(&_inv17); + _itemList.push_back(&_inv18); + _itemList.push_back(&_inv19); + _itemList.push_back(&_inv20); + _itemList.push_back(&_inv21); + _itemList.push_back(&_inv22); + _itemList.push_back(&_inv23); + _itemList.push_back(&_inv24); + _itemList.push_back(&_inv25); + _itemList.push_back(&_inv26); + _itemList.push_back(&_inv27); + _itemList.push_back(&_inv28); + _itemList.push_back(&_inv29); + _itemList.push_back(&_inv30); + _itemList.push_back(&_inv31); + _itemList.push_back(&_inv32); + _itemList.push_back(&_inv33); + _itemList.push_back(&_inv34); + _itemList.push_back(&_inv35); + _itemList.push_back(&_inv36); + _itemList.push_back(&_inv37); + _itemList.push_back(&_inv38); + _itemList.push_back(&_inv39); + _itemList.push_back(&_inv40); + _itemList.push_back(&_inv41); + _itemList.push_back(&_inv42); + _itemList.push_back(&_inv43); + _itemList.push_back(&_inv44); + _itemList.push_back(&_inv45); + _itemList.push_back(&_inv46); + _itemList.push_back(&_inv47); + _itemList.push_back(&_inv48); + _itemList.push_back(&_inv49); + _itemList.push_back(&_inv50); + _itemList.push_back(&_inv51); + _itemList.push_back(&_inv52); + + _selectedItem = NULL; +} + +void Ringworld2InvObjectList::reset() { + // Reset all object scene numbers + SynchronizedList<InvObject *>::iterator i; + for (i = _itemList.begin(); i != _itemList.end(); ++i) { + (*i)->_sceneNumber = 0; + } + + // Set up default inventory + setObjectScene(R2_1, 800); + setObjectScene(R2_2, 400); + setObjectScene(R2_3, 100); + setObjectScene(R2_STEPPING_DISKS, 100); + setObjectScene(R2_5, 400); + setObjectScene(R2_6, 400); + setObjectScene(R2_7, 500); + setObjectScene(R2_8, 700); + setObjectScene(R2_9, 800); + setObjectScene(R2_10, 100); + setObjectScene(R2_11, 400); + setObjectScene(R2_12, 500); + setObjectScene(R2_13, 1550); + setObjectScene(R2_14, 850); + setObjectScene(R2_15, 850); + setObjectScene(R2_16, 0); + setObjectScene(R2_17, 1550); + setObjectScene(R2_18, 1550); + setObjectScene(R2_19, 1550); + setObjectScene(R2_20, 500); + setObjectScene(R2_21, 500); + setObjectScene(R2_22, 1550); + setObjectScene(R2_23, 1580); + setObjectScene(R2_24, 9999); + setObjectScene(R2_25, 1550); + setObjectScene(R2_26, 1550); + setObjectScene(R2_27, 1580); + setObjectScene(R2_28, 1550); + setObjectScene(R2_29, 2525); + setObjectScene(R2_30, 2440); + setObjectScene(R2_31, 2455); + setObjectScene(R2_32, 2535); + setObjectScene(R2_33, 2530); + setObjectScene(R2_34, 1950); + setObjectScene(R2_35, 1950); + setObjectScene(R2_36, 9999); + setObjectScene(R2_37, 2430); + setObjectScene(R2_38, 9999); + setObjectScene(R2_39, 2); + setObjectScene(R2_40, 9999); + setObjectScene(R2_41, 3150); + setObjectScene(R2_42, 0); + setObjectScene(R2_43, 3260); + setObjectScene(R2_44, 2); + setObjectScene(R2_45, 1550); + setObjectScene(R2_46, 0); + setObjectScene(R2_47, 3150); + setObjectScene(R2_48, 2435); + setObjectScene(R2_49, 2440); + setObjectScene(R2_50, 2435); + setObjectScene(R2_51, 1580); + setObjectScene(R2_52, 3260); +} + +void Ringworld2InvObjectList::setObjectScene(int objectNum, int sceneNumber) { + // Find the appropriate object + int num = objectNum; + SynchronizedList<InvObject *>::iterator i = _itemList.begin(); + while (num-- > 0) ++i; + (*i)->_sceneNumber = sceneNumber; + + // If the item is the currently active one, default back to the use cursor + if (R2_GLOBALS._events.getCursor() == objectNum) + R2_GLOBALS._events.setCursor(CURSOR_USE); + + // Update the user interface if necessary + T2_GLOBALS._uiElements.updateInventory(); +} + +/*--------------------------------------------------------------------------*/ + +void Ringworld2Game::start() { + int slot = -1; + + if (ConfMan.hasKey("save_slot")) { + slot = ConfMan.getInt("save_slot"); + Common::String file = g_vm->generateSaveName(slot); + Common::InSaveFile *in = g_vm->_system->getSavefileManager()->openForLoading(file); + if (in) + delete in; + else + slot = -1; + } + + if (slot >= 0) + g_globals->_sceneHandler->_loadGameSlot = slot; + else { + // Switch to the first game scene + g_globals->_events.setCursor(CURSOR_WALK); + g_globals->_sceneManager.setNewScene(100); + } + + g_globals->_events.showCursor(); +} + +void Ringworld2Game::restart() { + g_globals->_scenePalette.clearListeners(); + g_globals->_soundHandler.stop(); + + // Change to the first game scene + g_globals->_sceneManager.changeScene(100); +} + +void Ringworld2Game::endGame(int resNum, int lineNum) { + g_globals->_events.setCursor(CURSOR_WALK); + Common::String msg = g_resourceManager->getMessage(resNum, lineNum); + bool savesExist = g_saver->savegamesExist(); + + if (!savesExist) { + // No savegames exist, so prompt the user to restart or quit + if (MessageDialog::show(msg, QUIT_BTN_STRING, RESTART_BTN_STRING) == 0) + g_vm->quitGame(); + else + restart(); + } else { + // Savegames exist, so prompt for Restore/Restart + bool breakFlag; + do { + if (g_vm->shouldQuit()) { + breakFlag = true; + } else if (MessageDialog::show(msg, RESTART_BTN_STRING, RESTORE_BTN_STRING) == 0) { + restart(); + breakFlag = true; + } else { + handleSaveLoad(false, g_globals->_sceneHandler->_loadGameSlot, g_globals->_sceneHandler->_saveName); + breakFlag = g_globals->_sceneHandler->_loadGameSlot >= 0; + } + } while (!breakFlag); + } + + g_globals->_events.setCursorFromFlag(); +} + +void Ringworld2Game::processEvent(Event &event) { + if (event.eventType == EVENT_KEYPRESS) { + switch (event.kbd.keycode) { + case Common::KEYCODE_F1: + // F1 - Help +// MessageDialog::show(HELP_MSG, OK_BTN_STRING); + break; + + case Common::KEYCODE_F2: + // F2 - Sound Options + SoundDialog::execute(); + break; + + case Common::KEYCODE_F3: + // F3 - Quit + quitGame(); + event.handled = false; + break; + + case Common::KEYCODE_F4: + // F4 - Restart + restartGame(); + g_globals->_events.setCursorFromFlag(); + break; + + case Common::KEYCODE_F7: + // F7 - Restore + restoreGame(); + g_globals->_events.setCursorFromFlag(); + break; + + case Common::KEYCODE_F10: + // F10 - Pause + GfxDialog::setPalette(); + MessageDialog::show(GAME_PAUSED_MSG, OK_BTN_STRING); + g_globals->_events.setCursorFromFlag(); + break; + + default: + break; + } + } +} + +void Ringworld2Game::rightClick() { +/* + RightClickDialog *dlg = new RightClickDialog(); + dlg->execute(); + delete dlg; +*/ +} + +/*--------------------------------------------------------------------------*/ + +NamedHotspot::NamedHotspot() : SceneHotspot() { + _resNum = 0; + _lookLineNum = _useLineNum = _talkLineNum = -1; +} + +bool NamedHotspot::startAction(CursorType action, Event &event) { + switch (action) { + case CURSOR_WALK: + // Nothing + return false; + case CURSOR_LOOK: + if (_lookLineNum == -1) + return SceneHotspot::startAction(action, event); + + SceneItem::display2(_resNum, _lookLineNum); + return true; + case CURSOR_USE: + if (_useLineNum == -1) + return SceneHotspot::startAction(action, event); + + SceneItem::display2(_resNum, _useLineNum); + return true; + case CURSOR_TALK: + if (_talkLineNum == -1) + return SceneHotspot::startAction(action, event); + + SceneItem::display2(_resNum, _talkLineNum); + return true; + default: + return SceneHotspot::startAction(action, event); + } +} + +void NamedHotspot::setDetails(int ys, int xs, int ye, int xe, const int resnum, const int lookLineNum, const int useLineNum) { + setBounds(ys, xe, ye, xs); + _resNum = resnum; + _lookLineNum = lookLineNum; + _useLineNum = useLineNum; + _talkLineNum = -1; + g_globals->_sceneItems.addItems(this, NULL); +} + +void NamedHotspot::setDetails(const Rect &bounds, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item) { + setBounds(bounds); + _resNum = resNum; + _lookLineNum = lookLineNum; + _talkLineNum = talkLineNum; + _useLineNum = useLineNum; + + switch (mode) { + case 2: + g_globals->_sceneItems.push_front(this); + break; + case 4: + g_globals->_sceneItems.addBefore(item, this); + break; + case 5: + g_globals->_sceneItems.addAfter(item, this); + break; + default: + g_globals->_sceneItems.push_back(this); + break; + } +} + +void NamedHotspot::setDetails(int sceneRegionId, int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode) { + _sceneRegionId = sceneRegionId; + _resNum = resNum; + _lookLineNum = lookLineNum; + _talkLineNum = talkLineNum; + _useLineNum = useLineNum; + + // Handle adding hotspot to scene items list as necessary + switch (mode) { + case 2: + GLOBALS._sceneItems.push_front(this); + break; + case 3: + break; + default: + GLOBALS._sceneItems.push_back(this); + break; + } +} + +void NamedHotspot::synchronize(Serializer &s) { + SceneHotspot::synchronize(s); + s.syncAsSint16LE(_resNum); + s.syncAsSint16LE(_lookLineNum); + s.syncAsSint16LE(_useLineNum); + + if (g_vm->getGameID() == GType_BlueForce) + s.syncAsSint16LE(_talkLineNum); +} + +void SceneActor::postInit(SceneObjectList *OwnerList) { + _lookLineNum = _talkLineNum = _useLineNum = -1; + SceneObject::postInit(); +} + +void SceneActor::synchronize(Serializer &s) { + SceneObject::synchronize(s); + s.syncAsSint16LE(_resNum); + s.syncAsSint16LE(_lookLineNum); + s.syncAsSint16LE(_talkLineNum); + s.syncAsSint16LE(_useLineNum); + + s.syncAsSint16LE(_effect); + s.syncAsSint16LE(_shade); +} + +bool SceneActor::startAction(CursorType action, Event &event) { + bool handled = true; + + switch (action) { + case CURSOR_LOOK: + if (_lookLineNum == -1) + handled = false; + else + SceneItem::display2(_resNum, _lookLineNum); + break; + case CURSOR_USE: + if (_useLineNum == -1) + handled = false; + else + SceneItem::display2(_resNum, _useLineNum); + break; + case CURSOR_TALK: + if (_talkLineNum == -1) + handled = false; + else + SceneItem::display2(_resNum, _talkLineNum); + break; + default: + handled = false; + break; + } + + if (!handled) + handled = ((SceneExt *)R2_GLOBALS._sceneManager._scene)->display(action); + return handled; +} + +void SceneActor::setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum, int mode, SceneItem *item) { + _resNum = resNum; + _lookLineNum = lookLineNum; + _talkLineNum = talkLineNum; + _useLineNum = useLineNum; + + switch (mode) { + case 2: + g_globals->_sceneItems.push_front(this); + break; + case 4: + g_globals->_sceneItems.addBefore(item, this); + break; + case 5: + g_globals->_sceneItems.addAfter(item, this); + break; + default: + g_globals->_sceneItems.push_back(this); + break; + } +} + +void SceneActor::setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum) { + _resNum = resNum; + _lookLineNum = lookLineNum; + _talkLineNum = talkLineNum; + _useLineNum = useLineNum; +} + + +} // End of namespace Ringworld2 + +} // End of namespace TsAGE |