Common::WriteStream *KyraEngine_v1::openSaveForWriting(const char *filename, const char *saveName, const Graphics::Surface *thumbnail) const { if (shouldQuit()) return 0; Common::WriteStream *out = 0; if (!(out = _saveFileMan->openForSaving(filename))) { warning("Can't create file '%s', game not saved", filename); return 0; } // Savegame version out->writeUint32BE(MKTAG('W', 'W', 'S', 'V')); out->writeByte(_flags.gameID); out->writeUint32BE(CURRENT_SAVE_VERSION); out->write(saveName, strlen(saveName) + 1); if (_flags.isTalkie) out->writeUint32BE(GF_TALKIE); else if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) out->writeUint32BE(GF_FMTOWNS); else out->writeUint32BE(GF_FLOPPY); if (out->err()) { warning("Can't write file '%s'. (Disk full?)", filename); delete out; return 0; } Graphics::Surface *genThumbnail = 0; if (!thumbnail) thumbnail = genThumbnail = generateSaveThumbnail(); if (thumbnail) Graphics::saveThumbnail(*out, *thumbnail); else Graphics::saveThumbnail(*out); if (genThumbnail) { genThumbnail->free(); delete genThumbnail; } return out; }
int AgiEngine::waitAnyKey() { int key = 0; clearKeyQueue(); debugC(3, kDebugLevelInput, "waiting... (any key)"); while (!(shouldQuit() || _restartGame)) { pollTimer(); key = doPollKeyboard(); if (key) break; _gfx->doUpdate(); } // Have to clear it as original did not set this variable, and we do it in doPollKeyboard() _game.keypress = 0; return key; }
void AGOSEngine_Feeble::playVideo(const char *filename, bool lastSceneUsed) { if (shouldQuit()) return; if (lastSceneUsed) setBitFlag(41, true); _moviePlayer = makeMoviePlayer(this, filename); assert(_moviePlayer); _moviePlayer->load(); _moviePlayer->play(); delete _moviePlayer; _moviePlayer = NULL; if (lastSceneUsed) setBitFlag(41, false); }
void AGOSEngine_Simon1::os1_pauseGame() { // 135: pause game _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true); // If all else fails, use English as fallback. Common::KeyCode keyYes = Common::KEYCODE_y; Common::KeyCode keyNo = Common::KEYCODE_n; switch (_language) { case Common::RU_RUS: break; case Common::PL_POL: keyYes = Common::KEYCODE_t; break; case Common::HE_ISR: keyYes = Common::KEYCODE_f; break; case Common::ES_ESP: keyYes = Common::KEYCODE_s; break; case Common::IT_ITA: keyYes = Common::KEYCODE_s; break; case Common::FR_FRA: keyYes = Common::KEYCODE_o; break; case Common::DE_DEU: keyYes = Common::KEYCODE_j; break; default: break; } while (!shouldQuit()) { delay(1); if (_keyPressed.keycode == keyYes) quitGame(); else if (_keyPressed.keycode == keyNo) break; } _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false); }
void App::run() { window_->show(); onStart(); double last_update_time = getTime(); while (!shouldQuit()) { processEvents(); double update_time = getTime(); double dt = update_time - last_update_time; last_update_time = update_time; onUpdate(dt); onRender(); window_->swapBuffers(); } onStop(); }
Common::Error KyraEngine_LoK::go() { if (_res->getFileSize("6.FNT")) _screen->loadFont(Screen::FID_6_FNT, "6.FNT"); _screen->loadFont(Screen::FID_8_FNT, "8FAT.FNT"); _screen->setFont(_flags.lang == Common::JA_JPN ? Screen::FID_SJIS_FNT : Screen::FID_8_FNT); _screen->setScreenDim(0); _abortIntroFlag = false; if (_flags.isDemo && !_flags.isTalkie) { _seqPlayerFlag = true; seq_demo(); _seqPlayerFlag = false; } else { setGameFlag(0xF3); setGameFlag(0xFD); if (_gameToLoad == -1) { setGameFlag(0xEF); _seqPlayerFlag = true; seq_intro(); _seqPlayerFlag = false; if (_flags.isDemo) { _screen->fadeToBlack(); return Common::kNoError; } if (shouldQuit()) return Common::kNoError; if (_skipIntroFlag && _abortIntroFlag && saveFileLoadable(0)) resetGameFlag(0xEF); } _eventList.clear(); startup(); resetGameFlag(0xEF); mainLoop(); } return Common::kNoError; }
void App::run() { init(); onSetup(); window_->show(); while (!shouldQuit()) { input_.update(); timer_.update(); processEvents(); if (screen_) { screen_->onUpdate(); screen_->onRender(); } window_->swapBuffers(); } destroy(); }
void TestbedEngine::invokeTestsuites(TestbedConfigManager &cfMan) { Common::Array<Testsuite *>::const_iterator iter; uint count = 1; Common::Point pt = Testsuite::getDisplayRegionCoordinates(); int numSuitesEnabled = cfMan.getNumSuitesEnabled(); if (!numSuitesEnabled) return; for (iter = _testsuiteList.begin(); iter != _testsuiteList.end(); iter++) { if (shouldQuit()) { return; } (*iter)->reset(); if ((*iter)->isEnabled()) { Testsuite::updateStats("Testsuite", (*iter)->getName(), count++, numSuitesEnabled, pt); (*iter)->execute(); } } }
void AGOSEngine_FeebleDemo::waitForSpace() { const char *message; if (_language == Common::DE_DEU) { message = "Dr\x81""cken Sie die <Leertaste>, um fortzufahren..."; } else { message = "Press <SPACE> to continue..."; } windowPutChar(_textWindow, 12); for (; *message; message++) windowPutChar(_textWindow, *message); mouseOff(); do { delay(1); } while (!shouldQuit() && (_keyPressed.keycode != Common::KEYCODE_SPACE)); _keyPressed.reset(); mouseOn(); }
void AgiEngine::interpretCycle() { int oldSound, oldScore; if (_game.playerControl) _game.vars[vEgoDir] = _game.viewTable[0].direction; else _game.viewTable[0].direction = _game.vars[vEgoDir]; checkAllMotions(); oldScore = _game.vars[vScore]; oldSound = getflag(fSoundOn); _game.exitAllLogics = false; while (runLogic(0) == 0 && !(shouldQuit() || _restartGame)) { _game.vars[vWordNotFound] = 0; _game.vars[vBorderTouchObj] = 0; _game.vars[vBorderCode] = 0; oldScore = _game.vars[vScore]; setflag(fEnteredCli, false); _game.exitAllLogics = false; resetControllers(); } resetControllers(); _game.viewTable[0].direction = _game.vars[vEgoDir]; if (_game.vars[vScore] != oldScore || getflag(fSoundOn) != oldSound) writeStatus(); _game.vars[vBorderTouchObj] = 0; _game.vars[vBorderCode] = 0; setflag(fNewRoomExec, false); setflag(fRestartGame, false); setflag(fRestoreJustRan, false); if (_game.gfxMode) { updateViewtable(); _gfx->doUpdate(); } }
bool KyraRpgEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) { if (!_sound->sfxEnabled() || shouldQuit()) return false; if (_environmentSfx) snd_playSoundEffect(_environmentSfx, _environmentSfxVol); int dist = 0; if (block) { dist = getBlockDistance(_currentBlock, block); if (dist > _envSfxDistThreshold) { _environmentSfx = 0; return false; } } _environmentSfx = soundId; _environmentSfxVol = (15 - ((block || (_flags.gameID == GI_LOL && dist < 2)) ? dist : 0)) << 4; return true; }
void CineEngine::showSplashScreen() { Common::File file; if (!file.open("sony.lbm")) return; Image::IFFDecoder decoder; if (!decoder.loadStream(file)) return; const Graphics::Surface *surface = decoder.getSurface(); if (surface->getWidth() == 640 && surface->getHeight() == 480) { initGraphics(640, 480, true); const byte *palette = decoder.getPalette(); int paletteColorCount = decoder.getPaletteColorCount(); g_system->getPaletteManager()->setPalette(palette, 0, paletteColorCount); g_system->copyRectToScreen(surface->getPixels(), 640, 0, 0, 640, 480); g_system->updateScreen(); Common::EventManager *eventMan = g_system->getEventManager(); bool done = false; uint32 now = g_system->getMillis(); while (!done && g_system->getMillis() - now < 2000) { Common::Event event; while (eventMan->pollEvent(event)) { if (event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) { done = true; break; } if (shouldQuit()) done = true; } } } decoder.destroy(); }
/** * Main game loop. Handles potentially playing the game multiple times, such as if the player * loses, and chooses to start playing the game again. */ void MortevielleEngine::mainGame() { if (_reloadCFIEC) loadCFIEC(); for (_crep = 1; _crep <= _x26KeyCount; ++_crep) decodeNumber(&_cfiecBuffer[161 * 16], (_cfiecBufferSize - (161 * 16)) / 64); _menu->initMenu(); charToHour(); initGame(); clearScreen(); drawRightFrame(); _mouse->showMouse(); // Loop to play the game do { playGame(); if (shouldQuit()) return; } while (!_quitGame); }
void SherlockEngine::sceneLoop() { while (!shouldQuit() && _scene->_goToScene == -1) { // See if a script needs to be completed from either a goto room code, // or a script that was interrupted by another script if (_talk->_scriptMoreFlag == 1 || _talk->_scriptMoreFlag == 3) _talk->talkTo(_talk->_scriptName); else _talk->_scriptMoreFlag = 0; // Handle any input from the keyboard or mouse handleInput(); if (_people->_savedPos.x == -1) { _canLoadSave = true; _scene->doBgAnim(); _canLoadSave = false; } } _scene->freeScene(); _people->freeWalk(); }
void DrasculaEngine::placeVonBraun(int pointX) { trackVonBraun = (pointX < vonBraunX) ? 0 : 1; vonBraunHasMoved = 1; while (!shouldQuit()) { updateEvents(); updateRoom(); updateScreen(); if (trackVonBraun == 0) { vonBraunX = vonBraunX - 5; if (vonBraunX <= pointX) break; } else { vonBraunX = vonBraunX + 5; if (vonBraunX >= pointX) break; } pause(5); } vonBraunHasMoved = 0; }
bool AGOSEngine::kickoffTimeEvents() { uint32 cur_time; TimeEvent *te; bool result = false; if (getGameType() == GType_FF && _clockStopped) return result; cur_time = getTime() - _gameStoppedClock; while ((te = _firstTimeStruct) != NULL && te->time <= cur_time && !shouldQuit()) { result = true; _pendingDeleteTimeEvent = te; invokeTimeEvent(te); if (_pendingDeleteTimeEvent) { _pendingDeleteTimeEvent = NULL; delTimeEvent(te); } } return result; }
Common::Error MohawkEngine_CSTime::run() { MohawkEngine::run(); _console = new CSTimeConsole(this); _gfx = new CSTimeGraphics(this); _cursor = new DefaultCursorManager(this, ID_CURS); _interface = new CSTimeInterface(this); _view = new CSTimeView(this); _view->setupView(); _view->setModule(new CSTimeModule(this)); while (!shouldQuit()) { switch (_state) { case kCSTStateStartup: // We just jump straight to the case for now. _state = kCSTStateNewCase; break; case kCSTStateNewCase: initCase(); _state = kCSTStateNewScene; break; case kCSTStateNewScene: nextScene(); _state = kCSTStateNormal; break; case kCSTStateNormal: update(); break; } } return Common::kNoError; }
void KyraEngine_HoF::bookLoop() { Button bookButtons[5]; GUI_V2_BUTTON(bookButtons[0], 0x24, 0, 0, 1, 1, 1, 0x4487, 0, 0x82, 0xBE, 0x0A, 0x0A, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); bookButtons[0].buttonCallback = BUTTON_FUNCTOR(KyraEngine_HoF, this, &KyraEngine_HoF::bookPrevPage); GUI_V2_BUTTON(bookButtons[1], 0x25, 0, 0, 1, 1, 1, 0x4487, 0, 0xB1, 0xBE, 0x0A, 0x0A, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); bookButtons[1].buttonCallback = BUTTON_FUNCTOR(KyraEngine_HoF, this, &KyraEngine_HoF::bookNextPage); GUI_V2_BUTTON(bookButtons[2], 0x26, 0, 0, 1, 1, 1, 0x4487, 0, 0x8F, 0xBE, 0x21, 0x0A, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); bookButtons[2].buttonCallback = BUTTON_FUNCTOR(KyraEngine_HoF, this, &KyraEngine_HoF::bookClose); GUI_V2_BUTTON(bookButtons[3], 0x27, 0, 0, 1, 1, 1, 0x4487, 0, 0x08, 0x08, 0x90, 0xB4, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); bookButtons[3].buttonCallback = BUTTON_FUNCTOR(KyraEngine_HoF, this, &KyraEngine_HoF::bookPrevPage); GUI_V2_BUTTON(bookButtons[4], 0x28, 0, 0, 1, 1, 1, 0x4487, 0, 0xAA, 0x08, 0x8E, 0xB4, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0); bookButtons[4].buttonCallback = BUTTON_FUNCTOR(KyraEngine_HoF, this, &KyraEngine_HoF::bookNextPage); Button *buttonList = 0; for (uint i = 0; i < ARRAYSIZE(bookButtons); ++i) buttonList = _gui->addButtonToList(buttonList, &bookButtons[i]); showBookPage(); _bookShown = true; while (_bookShown && !shouldQuit()) { checkInput(buttonList); removeInputTop(); if (_bookCurPage != _bookNewPage) { _bookCurPage = _bookNewPage; _screen->clearPage(2); loadBookBkgd(); showBookPage(); snd_playSoundEffect(0x64); _screen->copyRegion(0, 0, 0, 0, 0x140, 0xC8, 2, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); } _system->delayMillis(10); } _screen->clearPage(2); }
Common::Error AGOSEngine_FeebleDemo::go() { // Main menu defineBox( 1, 80, 75, 81, 117, kBFBoxDead, 0, NULL); defineBox( 2, 267, 21, 105, 97, kBFBoxDead, 0, NULL); defineBox( 3, 456, 89, 125, 103, kBFBoxDead, 0, NULL); defineBox( 4, 151, 225, 345, 41, kBFBoxDead, 0, NULL); defineBox( 5, 169, 319, 109, 113, kBFBoxDead, 0, NULL); defineBox( 6, 404, 308, 62, 117, kBFBoxDead, 0, NULL); // Film menu defineBox(11, 28, 81, 123, 93, kBFBoxDead, 0, NULL); defineBox(12, 182, 81, 123, 93, kBFBoxDead, 0, NULL); defineBox(13, 335, 81, 123, 93, kBFBoxDead, 0, NULL); defineBox(14, 488, 81, 123, 93, kBFBoxDead, 0, NULL); defineBox(15, 28, 201, 123, 93, kBFBoxDead, 0, NULL); defineBox(16, 182, 201, 123, 93, kBFBoxDead, 0, NULL); defineBox(17, 335, 201, 123, 93, kBFBoxDead, 0, NULL); defineBox(18, 488, 201, 123, 93, kBFBoxDead, 0, NULL); defineBox(19, 255, 357, 135, 45, kBFBoxDead, 0, NULL); // Exit Menu defineBox(21, 548, 421, 42, 21, kBFBoxDead, 0, NULL); // Text Window used by Feeble Files Data section if (_language ==Common::DE_DEU) { _textWindow = openWindow(322, 457, 196, 15, 1, 0, 255); } else { _textWindow = openWindow(444, 452, 196, 15, 1, 0, 255); } playVideo("winasoft.smk"); playVideo("fbigtalk.smk"); while (!shouldQuit()) mainMenu(); return Common::kNoError; }
void DrasculaEngine::gotoObject(int pointX, int pointY) { bool cursorVisible = isCursorVisible(); hideCursor(); if (currentChapter == 5 || currentChapter == 6) { if (hare_se_ve == 0) { curX = roomX; curY = roomY; updateRoom(); updateScreen(); return; } } roomX = pointX; roomY = pointY; startWalking(); while (!shouldQuit()) { updateRoom(); updateScreen(); updateEvents(); if (characterMoved == 0) break; pause(3); } if (walkToObject == 1) { walkToObject = 0; trackProtagonist = trackFinal; } updateRoom(); updateScreen(); // roomNumber -2 is end credits. Do not show cursor there if (cursorVisible && roomNumber != -2) showCursor(); }
bool MartianEngine::showCredits() { _events->hideCursor(); _screen->clearScreen(); _destIn = _screen; int posX = _creditsStream->readSint16LE(); int posY = 0; while(posX != -1) { posY = _creditsStream->readSint16LE(); int frameNum = _creditsStream->readSint16LE(); _screen->plotImage(_introObjects, frameNum, Common::Point(posX, posY)); posX = _creditsStream->readSint16LE(); } posY = _creditsStream->readSint16LE(); if (posY == -1) { _events->showCursor(); _screen->forceFadeOut(); return true; } _screen->forceFadeIn(); _timers[3]._timer = _timers[3]._initTm = posY; while (!shouldQuit() && !_events->isKeyMousePressed() && _timers[3]._timer) { _events->pollEventsAndWait(); } _events->showCursor(); _screen->forceFadeOut(); if (_events->_rightButton) return true; else return false; }
void LabEngine::processJournal() { while (1) { IntuiMessage *msg = _event->getMsg(); if (shouldQuit()) { _quitLab = true; return; } updateEvents(); _graphics->screenUpdate(); _system->delayMillis(10); if (!msg) continue; MessageClass msgClass = msg->_msgClass; if ((msgClass == kMessageRightClick) || ((msgClass == kMessageRawKey) && (msg->_code == Common::KEYCODE_ESCAPE))) return; else if (msgClass == kMessageButtonUp) { uint16 buttonId = msg->_code; if (buttonId == 0) { if (_journalPage >= 2) { _journalPage -= 2; drawJournal(1, false); } } else if (buttonId == 1) { return; } else if (buttonId == 2) { if (!_lastPage) { _journalPage += 2; drawJournal(2, false); } } } } // while }
Common::Error GagEngine::run() { Init(); Common::Error status; do { // do periodic processing uint32 time_start = _system->getMillis(); status = Update(); uint32 time_end = _system->getMillis(); // wrap around check uint32 time_spent = time_end >= time_start ? time_end - time_start : std::numeric_limits<uint32>::max() - time_start + time_end + 1; // sleep remaining frame time uint time_for_frame = 1000 / _SCREEN_FPS; _system->delayMillis(time_spent < time_for_frame ? time_for_frame - time_spent : 0); } while(status.getCode() == Common::kNoError && !shouldQuit()); return status; }
zchar Processor::stream_read_input(int max, zchar *buf, zword timeout, zword routine, bool hot_keys, bool no_scripting) { zchar key = ZC_BAD; flush_buffer(); // Remove initial input from the transscript file or from the screen if (ostream_script && enable_scripting && !no_scripting) script_erase_input(buf); // Read input line from current input stream continue_input: do { if (istream_replay) key = replay_read_input(buf); else key = console_read_input(max, buf, timeout, key != ZC_BAD); if (shouldQuit()) return ZC_BAD; } while (key == ZC_BAD); // Copy input line to the command file if (ostream_record && !istream_replay) record_write_input(buf, key); // Handle timeouts if (key == ZC_TIME_OUT) if (direct_call(routine) == 0) goto continue_input; // Copy input line to transscript file or to the screen if (ostream_script && enable_scripting && !no_scripting) script_write_input(buf, key); // Return terminating key return key; }
int AgiEngine::waitKey() { int key = 0; clearKeyQueue(); debugC(3, kDebugLevelInput, "waiting..."); while (!(shouldQuit() || _restartGame || getflag(fRestoreJustRan))) { pollTimer(); key = doPollKeyboard(); if (key == KEY_ENTER || key == KEY_ESCAPE || key == BUTTON_LEFT) break; pollTimer(); updateTimer(); _gfx->doUpdate(); } // Have to clear it as original did not set this variable, and we do it in doPollKeyboard() // Fixes bug #2823759 _game.keypress = 0; return key; }
Common::Error HugoEngine::run() { s_Engine = this; initGraphics(320, 200, false); _mouse = new MouseHandler(this); _inventory = new InventoryHandler(this); _route = new Route(this); _sound = new SoundHandler(this); // Setup mixer syncSoundSettings(); _text = new TextHandler(this); _topMenu = new TopMenu(this); switch (_gameVariant) { case kGameVariantH1Win: // H1 Win _file = new FileManager_v1w(this); _scheduler = new Scheduler_v1w(this); _intro = new intro_v1w(this); _screen = new Screen_v1w(this); _parser = new Parser_v1w(this); _object = new ObjectHandler_v1w(this); _normalTPS = 9; break; case kGameVariantH2Win: _file = new FileManager_v2w(this); _scheduler = new Scheduler_v1w(this); _intro = new intro_v2w(this); _screen = new Screen_v1w(this); _parser = new Parser_v1w(this); _object = new ObjectHandler_v1w(this); _normalTPS = 9; break; case kGameVariantH3Win: _file = new FileManager_v2w(this); _scheduler = new Scheduler_v1w(this); _intro = new intro_v3w(this); _screen = new Screen_v1w(this); _parser = new Parser_v1w(this); _object = new ObjectHandler_v1w(this); _normalTPS = 9; break; case kGameVariantH1Dos: // H1 DOS _file = new FileManager_v1d(this); _scheduler = new Scheduler_v1d(this); _intro = new intro_v1d(this); _screen = new Screen_v1d(this); _parser = new Parser_v1d(this); _object = new ObjectHandler_v1d(this); _normalTPS = 8; break; case kGameVariantH2Dos: _file = new FileManager_v2d(this); _scheduler = new Scheduler_v2d(this); _intro = new intro_v2d(this); _screen = new Screen_v1d(this); _parser = new Parser_v2d(this); _object = new ObjectHandler_v2d(this); _normalTPS = 8; break; case kGameVariantH3Dos: _file = new FileManager_v3d(this); _scheduler = new Scheduler_v3d(this); _intro = new intro_v3d(this); _screen = new Screen_v1d(this); _parser = new Parser_v3d(this); _object = new ObjectHandler_v3d(this); _normalTPS = 9; break; } if (!loadHugoDat()) return Common::kUnknownError; // Use Windows-looking mouse cursor _screen->setCursorPal(); _screen->resetInventoryObjId(); _scheduler->initCypher(); initStatus(); // Initialize game status initConfig(); // Initialize user's config if (!_status._doQuitFl) { initialize(); resetConfig(); // Reset user's config initMachine(); // Start the state machine _status._viewState = kViewIntroInit; int16 loadSlot = Common::ConfigManager::instance().getInt("save_slot"); if (loadSlot >= 0) { _status._skipIntroFl = true; _file->restoreGame(loadSlot); } else { _file->saveGame(0, "New Game"); } } while (!_status._doQuitFl) { _screen->drawBoundaries(); g_system->updateScreen(); runMachine(); // Handle input Common::Event event; while (_eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_KEYDOWN: _parser->keyHandler(event); break; case Common::EVENT_MOUSEMOVE: _mouse->setMouseX(event.mouse.x); _mouse->setMouseY(event.mouse.y); break; case Common::EVENT_LBUTTONUP: _mouse->setLeftButton(); break; case Common::EVENT_RBUTTONUP: _mouse->setRightButton(); break; case Common::EVENT_QUIT: _status._doQuitFl = true; break; default: break; } } if (_status._helpFl) { _status._helpFl = false; _file->instructions(); } _mouse->mouseHandler(); // Mouse activity - adds to display list _screen->displayList(kDisplayDisplay); // Blit the display list to screen _status._doQuitFl |= shouldQuit(); // update game quit flag } return Common::kNoError; }
void LabEngine::doActions(const ActionList &actionList) { ActionList::const_iterator action; for (action = actionList.begin(); action != actionList.end(); ++action) { updateEvents(); if (_quitLab || shouldQuit()) return; switch (action->_actionType) { case kActionPlaySound: _music->loadSoundEffect(action->_messages[0], false, true); break; case kActionPlaySoundNoWait: // only used in scene 7 (street, when teleporting to the surreal maze) _music->loadSoundEffect(action->_messages[0], false, false); break; case kActionPlaySoundLooping: _music->loadSoundEffect(action->_messages[0], true, false); break; case kActionShowDiff: _graphics->readPict(action->_messages[0], true); break; case kActionShowDiffLooping: // used in scene 44 (heart of the labyrinth, minotaur) _graphics->readPict(action->_messages[0], false); break; case kActionLoadDiff: if (!action->_messages[0].empty()) // Puts a file into memory _graphics->loadPict(action->_messages[0]); break; case kActionLoadBitmap: error("Unused opcode kActionLoadBitmap has been called"); case kActionShowBitmap: error("Unused opcode kActionShowBitmap has been called"); case kActionTransition: _graphics->doTransition((TransitionType)action->_param1, action->_messages[0].c_str()); break; case kActionNoUpdate: _noUpdateDiff = true; _anim->_doBlack = false; break; case kActionForceUpdate: _curFileName = " "; break; case kActionShowCurPict: { Common::String test = getPictName(true); if (test != _curFileName) { _curFileName = test; _graphics->readPict(_curFileName); } } break; case kActionSetElement: _conditions->inclElement(action->_param1); break; case kActionUnsetElement: _conditions->exclElement(action->_param1); break; case kActionShowMessage: if (_graphics->_longWinInFront) _graphics->longDrawMessage(action->_messages[0], true); else _graphics->drawMessage(action->_messages[0], true); break; case kActionCShowMessage: if (!_closeDataPtr) _graphics->drawMessage(action->_messages[0], true); break; case kActionShowMessages: _graphics->drawMessage(action->_messages[_utils->getRandom(action->_param1)], true); break; case kActionChangeRoom: if (action->_param1 & 0x8000) { // This is a Wyrmkeep Windows trial version, thus stop at this // point, since we can't check for game payment status _graphics->readPict(getPictName(true)); GUI::MessageDialog trialMessage("This is the end of the trial version. You can play the full game using the original interpreter from Wyrmkeep"); trialMessage.runModal(); break; } _music->checkRoomMusic(_roomNum, action->_param1); _roomNum = action->_param1; _direction = action->_param2 - 1; _closeDataPtr = nullptr; _anim->_doBlack = true; break; case kActionSetCloseup: { Common::Point curPos = Common::Point(_utils->scaleX(action->_param1), _utils->scaleY(action->_param2)); const CloseData *tmpClosePtr = getObject(curPos, _closeDataPtr); if (tmpClosePtr) _closeDataPtr = tmpClosePtr; } break; case kActionMainView: _closeDataPtr = nullptr; break; case kActionSubInv: if (_inventory[action->_param1]._quantity) (_inventory[action->_param1]._quantity)--; if (_inventory[action->_param1]._quantity == 0) _conditions->exclElement(action->_param1); break; case kActionAddInv: (_inventory[action->_param1]._quantity) += action->_param2; _conditions->inclElement(action->_param1); break; case kActionShowDir: _graphics->setActionMessage(false); break; case kActionWaitSecs: { uint32 targetMillis = _system->getMillis() + action->_param1 * 1000; _graphics->screenUpdate(); while (_system->getMillis() < targetMillis) { updateEvents(); if (_quitLab || shouldQuit()) return; _anim->diffNextFrame(); } } break; case kActionStopMusic: // used in scene 44 (heart of the labyrinth, minotaur) _music->freeMusic(); break; case kActionStartMusic: // unused error("Unused opcode kActionStartMusic has been called"); break; case kActionChangeMusic: // used in scene 46 (museum exhibit, for the alarm) _music->changeMusic(action->_messages[0], true, false); break; case kActionResetMusic: // used in scene 45 (sheriff's office, after museum) _music->resetMusic(true); break; case kActionFillMusic: error("Unused opcode kActionFillMusic has been called"); break; case kActionWaitSound: // used in scene 44 (heart of the labyrinth / ending) while (_music->isSoundEffectActive()) { updateEvents(); if (_quitLab || shouldQuit()) return; _anim->diffNextFrame(); waitTOF(); } break; case kActionClearSound: _music->stopSoundEffect(); break; case kActionWinMusic: // used in scene 44 (heart of the labyrinth / ending) _music->freeMusic(); _music->changeMusic("Music:WinGame", false, false); break; case kActionWinGame: // used in scene 44 (heart of the labyrinth / ending) _quitLab = true; showLab2Teaser(); break; case kActionLostGame: error("Unused opcode kActionLostGame has been called"); case kActionResetBuffer: _graphics->freePict(); break; case kActionSpecialCmd: if (action->_param1 == 0) _anim->_doBlack = true; else if (action->_param1 == 1) _anim->_doBlack = (_closeDataPtr == nullptr); else if (action->_param1 == 2) _anim->_doBlack = (_closeDataPtr != nullptr); else if (action->_param1 == 5) { // inverse the palette for (int idx = (8 * 3); idx < (255 * 3); idx++) _anim->_diffPalette[idx] = 255 - _anim->_diffPalette[idx]; waitTOF(); _graphics->setPalette(_anim->_diffPalette, 256); waitTOF(); waitTOF(); } else if (action->_param1 == 4) { // white the palette _graphics->whiteScreen(); waitTOF(); waitTOF(); } else if (action->_param1 == 6) { // Restore the palette waitTOF(); _graphics->setPalette(_anim->_diffPalette, 256); waitTOF(); waitTOF(); } else if (action->_param1 == 7) { // Quick pause waitTOF(); waitTOF(); waitTOF(); } break; } } _music->stopSoundEffect(); }
Common::Error Sword2Engine::run() { // Get some falling RAM and put it in your pocket, never let it slip // away _debugger = NULL; _sound = NULL; _fontRenderer = NULL; _screen = NULL; _mouse = NULL; _logic = NULL; _resman = NULL; _memory = NULL; initGraphics(640, 480, true); _screen = new Screen(this, 640, 480); // Create the debugger as early as possible (but not before the // screen object!) so that errors can be displayed in it. In // particular, we want errors about missing files to be clearly // visible to the user. _debugger = new Debugger(this); _memory = new MemoryManager(this); _resman = new ResourceManager(this); if (!_resman->init()) return Common::kUnknownError; _logic = new Logic(this); _fontRenderer = new FontRenderer(this); _sound = new Sound(this); _mouse = new Mouse(this); registerDefaultSettings(); readSettings(); initStartMenu(); // During normal gameplay, we care neither about mouse button releases // nor the scroll wheel. setInputEventFilter(RD_LEFTBUTTONUP | RD_RIGHTBUTTONUP | RD_WHEELUP | RD_WHEELDOWN); setupPersistentResources(); initialiseFontResourceFlags(); if (_features & GF_DEMO) _logic->writeVar(DEMO, 1); else _logic->writeVar(DEMO, 0); if (_saveSlot != -1) { if (saveExists(_saveSlot)) restoreGame(_saveSlot); else { RestoreDialog dialog(this); if (!dialog.runModal()) startGame(); } } else if (!_bootParam && saveExists() && !isPsx()) { // Initial load/restart panel disabled in PSX int32 pars[2] = { 221, FX_LOOP }; // version because of missing panel resources bool result; _mouse->setMouse(NORMAL_MOUSE_ID); _logic->fnPlayMusic(pars); StartDialog dialog(this); result = (dialog.runModal() != 0); // If the game is started from the beginning, the cutscene // player will kill the music for us. Otherwise, the restore // will either have killed the music, or done a crossfade. if (shouldQuit()) return Common::kNoError; if (result) startGame(); } else startGame(); _screen->initialiseRenderCycle(); while (1) { _debugger->onFrame(); // Handle GMM Loading if (_gmmLoadSlot != -1) { // Hide mouse cursor and fade screen _mouse->hideMouse(); _screen->fadeDown(); // Clean up and load game _logic->_router->freeAllRouteMem(); // TODO: manage error handling restoreGame(_gmmLoadSlot); // Reset load slot _gmmLoadSlot = -1; // Show mouse _mouse->addHuman(); } KeyboardEvent *ke = keyboardEvent(); if (ke) { if ((ke->kbd.hasFlags(Common::KBD_CTRL) && ke->kbd.keycode == Common::KEYCODE_d) || ke->kbd.ascii == '#' || ke->kbd.ascii == '~') { _debugger->attach(); } else if (ke->kbd.hasFlags(0) || ke->kbd.hasFlags(Common::KBD_SHIFT)) { switch (ke->kbd.keycode) { case Common::KEYCODE_p: if (isPaused()) { _screen->dimPalette(false); pauseEngine(false); } else { pauseEngine(true); _screen->dimPalette(true); } break; #if 0 // Disabled because of strange rumors about the // credits running spontaneously every few // minutes. case Common::KEYCODE_c: if (!_logic->readVar(DEMO) && !_mouse->isChoosing()) { ScreenInfo *screenInfo = _screen->getScreenInfo(); _logic->fnPlayCredits(NULL); screenInfo->new_palette = 99; } break; #endif default: break; } } } // skip GameCycle if we're paused if (!isPaused()) { _gameCycle++; gameCycle(); } // We can't use this as termination condition for the loop, // because we want the break to happen before updating the // screen again. if (shouldQuit()) break; // creates the debug text blocks _debugger->buildDebugText(); _screen->buildDisplay(); } return Common::kNoError; }
void DrasculaEngine::volumeControls() { if (_lang == kSpanish) loadPic(95, tableSurface); copyRect(1, 56, 73, 63, 177, 97, tableSurface, screenSurface); updateScreen(73, 63, 73, 63, 177, 97, screenSurface); setCursor(kCursorCrosshair); showCursor(); while (!shouldQuit()) { int masterVolume = CLIP((_mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType) / 16), 0, 15); int voiceVolume = CLIP((_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) / 16), 0, 15); int musicVolume = CLIP((_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) / 16), 0, 15); int masterVolumeY = 72 + 61 - masterVolume * 4; int voiceVolumeY = 72 + 61 - voiceVolume * 4; int musicVolumeY = 72 + 61 - musicVolume * 4; updateRoom(); copyRect(1, 56, 73, 63, 177, 97, tableSurface, screenSurface); copyBackground(183, 56, 82, masterVolumeY, 39, 2 + masterVolume * 4, tableSurface, screenSurface); copyBackground(183, 56, 138, voiceVolumeY, 39, 2 + voiceVolume * 4, tableSurface, screenSurface); copyBackground(183, 56, 194, musicVolumeY, 39, 2 + musicVolume * 4, tableSurface, screenSurface); updateScreen(); updateEvents(); // we're ignoring keypresses, so just empty the keyboard buffer while (getScan()) ; if (rightMouseButton == 1) { delay(100); break; } if (leftMouseButton == 1) { delay(100); if (mouseX > 80 && mouseX < 121) { updateVolume(Audio::Mixer::kPlainSoundType, masterVolumeY); } if (mouseX > 136 && mouseX < 178) { updateVolume(Audio::Mixer::kSpeechSoundType, voiceVolumeY); } if (mouseX > 192 && mouseX < 233) { updateVolume(Audio::Mixer::kMusicSoundType, musicVolumeY); } } } if (_lang == kSpanish) loadPic(974, tableSurface); selectVerb(kVerbNone); updateEvents(); }
void CineEngine::mainLoop(int bootScriptIdx) { bool playerAction; byte di; uint16 mouseButton; if (_preLoad == false) { resetBgIncrustList(); setTextWindow(0, 0, 20, 200); errorVar = 0; addScriptToGlobalScripts(bootScriptIdx); menuVar = 0; // gfxRedrawPage(page0c, page0, page0c, page0, -1); // gfxWaitVBL(); // gfxRedrawMouseCursor(); inMenu = false; allowPlayerInput = 0; checkForPendingDataLoadSwitch = 0; fadeRequired = false; isDrawCommandEnabled = 0; waitForPlayerClick = 0; menuCommandLen = 0; playerCommand = -1; g_cine->_commandBuffer = ""; g_cine->_globalVars[VAR_MOUSE_X_POS] = 0; g_cine->_globalVars[VAR_MOUSE_Y_POS] = 0; if (g_cine->getGameType() == Cine::GType_OS) { g_cine->_globalVars[VAR_MOUSE_X_POS_2ND] = 0; g_cine->_globalVars[VAR_MOUSE_Y_POS_2ND] = 0; g_cine->_globalVars[VAR_BYPASS_PROTECTION] = 0; // set to 1 to bypass the copy protection g_cine->_globalVars[VAR_LOW_MEMORY] = 0; // set to 1 to disable some animations, sounds etc. } strcpy(newPrcName, ""); strcpy(newRelName, ""); strcpy(newObjectName, ""); strcpy(newMsgName, ""); strcpy(currentCtName, ""); strcpy(currentPartName, ""); g_sound->stopMusic(); } do { // HACK: Force amount of oxygen left to maximum during Operation Stealth's first arcade sequence. // This makes it possible to pass the arcade sequence for now. // FIXME: Remove the hack and make the first arcade sequence normally playable. if (g_cine->getGameType() == Cine::GType_OS) { Common::String bgName(renderer->getBgName()); // Check if the background is one of the three backgrounds // that are only used during the first arcade sequence. if (bgName == "28.PI1" || bgName == "29.PI1" || bgName == "30.PI1") { static const uint oxygenObjNum = 202, maxOxygen = 264; // Force the amount of oxygen left to the maximum. g_cine->_objectTable[oxygenObjNum].x = maxOxygen; } } // HACK: In Operation Stealth after the first arcade sequence jump player's position to avoid getting stuck. // After the first arcade sequence the player comes up stairs from // the water in Santa Paragua's downtown in front of the flower shop. // Previously he was completely stuck after getting up the stairs. // If the background is the one used in the flower shop scene ("21.PI1") // and the player is at the exact location after getting up the stairs // then we just nudge him a tiny bit away from the stairs and voila, he's free! // Maybe the real problem behind all this is collision data related as it looks // like there's some boundary right there near position (204, 110) which we can // jump over by moving the character to (204, 109). The script handling the // flower shop scene is AIRPORT.PRC's 13th script. // FIXME: Remove the hack and solve what's really causing the problem in the first place. if (g_cine->getGameType() == Cine::GType_OS) { if (scumm_stricmp(renderer->getBgName(), "21.PI1") == 0 && g_cine->_objectTable[1].x == 204 && g_cine->_objectTable[1].y == 110) { g_cine->_objectTable[1].y--; // Move the player character upward on-screen by one pixel } } stopMusicAfterFadeOut(); di = executePlayerInput(); // Clear the zoneQuery table (Operation Stealth specific) if (g_cine->getGameType() == Cine::GType_OS) { Common::set_to(g_cine->_zoneQuery.begin(), g_cine->_zoneQuery.end(), 0); } if (g_cine->getGameType() == Cine::GType_OS) { processSeqList(); } executeObjectScripts(); executeGlobalScripts(); purgeObjectScripts(); purgeGlobalScripts(); if (g_cine->getGameType() == Cine::GType_OS) { purgeSeqList(); } if (playerCommand == -1) { setMouseCursor(MOUSE_CURSOR_NORMAL); } else { setMouseCursor(MOUSE_CURSOR_CROSS); } if (renderer->ready()) { renderer->drawFrame(); } // NOTE: In the original Future Wars and Operation Stealth messages // were removed when running the drawOverlays function which is // currently called from the renderer's drawFrame function. removeMessages(); if (waitForPlayerClick) { playerAction = false; _messageLen <<= 3; if (_messageLen < 0x800) _messageLen = 0x800; do { manageEvents(); getMouseData(mouseUpdateStatus, &mouseButton, &dummyU16, &dummyU16); } while (mouseButton != 0 && !shouldQuit()); menuVar = 0; do { manageEvents(); getMouseData(mouseUpdateStatus, &mouseButton, &dummyU16, &dummyU16); playerAction = (mouseButton != 0) || processKeyboard(menuVar); mainLoopSub6(); } while (!playerAction && !shouldQuit()); menuVar = 0; do { manageEvents(); getMouseData(mouseUpdateStatus, &mouseButton, &dummyU16, &dummyU16); } while (mouseButton != 0 && !shouldQuit()); waitForPlayerClick = 0; } if (checkForPendingDataLoadSwitch) { checkForPendingDataLoad(); checkForPendingDataLoadSwitch = 0; } if (di) { if ("quit"[menuCommandLen] == (char)di) { ++menuCommandLen; if (menuCommandLen == 4) { quitGame(); } } else { menuCommandLen = 0; } } manageEvents(); } while (!shouldQuit() && !_restartRequested); hideMouse(); g_sound->stopMusic(); // if (g_cine->getGameType() == Cine::GType_OS) { // freeUnkList(); // } closePart(); }