Common::Error ZVision::run() { initialize(); // Check if a saved game is to be loaded from the launcher if (ConfMan.hasKey("save_slot")) _saveManager->loadGame(ConfMan.getInt("save_slot")); bool foundAllFonts = true; // Before starting, make absolutely sure that the user has copied the needed fonts for (int i = 0; i < FONT_COUNT; i++) { FontStyle curFont = getSystemFont(i); Common::String freeFontBoldItalic = Common::String("Bold") + curFont.freeFontItalicName; const char *fontSuffixes[4] = { "", "bd", "i", "bi" }; const char *freeFontSuffixes[4] = { "", "Bold", curFont.freeFontItalicName, freeFontBoldItalic.c_str() }; const char *liberationFontSuffixes[4] = { "-Regular", "-Bold", "-Italic", "-BoldItalic" }; for (int j = 0; j < 4; j++) { Common::String fontName = curFont.fontBase; if (fontName == "censcbk" && j > 0) fontName = "schlbk"; fontName += fontSuffixes[j]; fontName += ".ttf"; if (fontName == "schlbkbd.ttf") fontName = "schlbkb.ttf"; if (fontName == "garabi.ttf") continue; if (fontName == "garai.ttf") fontName = "garait.ttf"; Common::String freeFontName = curFont.freeFontBase; freeFontName += freeFontSuffixes[j]; freeFontName += ".ttf"; Common::String liberationFontName = curFont.liberationFontBase; liberationFontName += liberationFontSuffixes[j]; liberationFontName += ".ttf"; if (!Common::File::exists(fontName) && !_searchManager->hasFile(fontName) && !Common::File::exists(liberationFontName) && !_searchManager->hasFile(liberationFontName) && !Common::File::exists(freeFontName) && !_searchManager->hasFile(freeFontName)) { foundAllFonts = false; break; } } if (!foundAllFonts) break; } if (!foundAllFonts) { GUI::MessageDialog dialog( "Before playing this game, you'll need to copy the required " "fonts into ScummVM's extras directory, or into the game directory. " "On Windows, you'll need the following font files from the Windows " "font directory: Times New Roman, Century Schoolbook, Garamond, " "Courier New and Arial. Alternatively, you can download the " "Liberation Fonts or the GNU FreeFont package. You'll need all the " "fonts from the font package you choose, i.e., LiberationMono, " "LiberationSans and LiberationSerif, or FreeMono, FreeSans and " "FreeSerif respectively." ); dialog.runModal(); quitGame(); return Common::kUnknownError; } // Main loop while (!shouldQuit()) { _clock.update(); uint32 currentTime = _clock.getLastMeasuredTime(); uint32 deltaTime = _clock.getDeltaTime(); _cursorManager->setItemID(_scriptManager->getStateValue(StateKey_InventoryItem)); processEvents(); _renderManager->updateRotation(); _scriptManager->update(deltaTime); _menu->process(deltaTime); // Render the backBuffer to the screen _renderManager->prepareBackground(); _renderManager->renderMenuToScreen(); _renderManager->processSubs(deltaTime); _renderManager->renderSceneToScreen(); // Update the screen if (canRender()) { _system->updateScreen(); _renderedFrameCount++; } else { _frameRenderDelay--; } // Calculate the frame delay based off a desired frame time int delay = _desiredFrameTime - int32(_system->getMillis() - currentTime); // Ensure non-negative delay = delay < 0 ? 0 : delay; if (_doubleFPS) { delay >>= 1; } if (canSaveGameStateCurrently() && shouldPerformAutoSave(_saveManager->getLastSaveTime())) { _saveManager->autoSave(); } _system->delayMillis(delay); } return Common::kNoError; }
void ScummEngine::parseEvent(Common::Event event) { switch (event.type) { case Common::EVENT_KEYDOWN: if (event.kbd.keycode >= Common::KEYCODE_0 && event.kbd.keycode <= Common::KEYCODE_9 && ((event.kbd.hasFlags(Common::KBD_ALT) && canSaveGameStateCurrently()) || (event.kbd.hasFlags(Common::KBD_CTRL) && canLoadGameStateCurrently()))) { _saveLoadSlot = event.kbd.keycode - Common::KEYCODE_0; // don't overwrite autosave (slot 0) if (_saveLoadSlot == 0) _saveLoadSlot = 10; _saveLoadDescription = Common::String::format("Quicksave %d", _saveLoadSlot); _saveLoadFlag = (event.kbd.hasFlags(Common::KBD_ALT)) ? 1 : 2; _saveTemporaryState = false; } else if (event.kbd.hasFlags(Common::KBD_CTRL) && event.kbd.keycode == Common::KEYCODE_f) { _fastMode ^= 1; } else if (event.kbd.hasFlags(Common::KBD_CTRL) && event.kbd.keycode == Common::KEYCODE_g) { _fastMode ^= 2; } else if ((event.kbd.hasFlags(Common::KBD_CTRL) && event.kbd.keycode == Common::KEYCODE_d) || event.kbd.ascii == '~' || event.kbd.ascii == '#') { _debugger->attach(); } else if (event.kbd.hasFlags(Common::KBD_CTRL) && event.kbd.keycode == Common::KEYCODE_s) { _res->resourceStats(); } else { // Normal key press, pass on to the game. _keyPressed = event.kbd; } // FIXME: We are using ASCII values to index the _keyDownMap here, // yet later one code which checks _keyDownMap will use KEYCODEs // to do so. That is, we are mixing ascii and keycode values here, // which is bad. We probably should be only using keycodes, but at // least INSANE checks for "Shift-V" by looking for the 'V' key // being pressed. It would be easy to solve that by also storing // the modifier flags. However, since getKeyState() is also called // by scripts, we have to be careful with semantic changes. if (_keyPressed.ascii >= 512) debugC(DEBUG_GENERAL, "_keyPressed > 512 (%d)", _keyPressed.ascii); else _keyDownMap[_keyPressed.ascii] = true; break; case Common::EVENT_KEYUP: if (event.kbd.ascii >= 512) { debugC(DEBUG_GENERAL, "keyPressed > 512 (%d)", event.kbd.ascii); } else { _keyDownMap[event.kbd.ascii] = false; // Due to some weird bug with capslock key pressed // generated keydown event is for lower letter but // keyup is for upper letter // On most (all?) keyboards it is safe to assume that // both upper and lower letters are unpressed on keyup event // // Fixes bug #1709430: "FT: CAPSLOCK + V enables cheating for all fights" // // Fingolfin remarks: This wouldn't be a problem if we used keycodes. _keyDownMap[toupper(event.kbd.ascii)] = false; } break; // We update the mouse position whenever the mouse moves or a click occurs. // The latter is done to accomodate systems with a touchpad / pen controller. case Common::EVENT_LBUTTONDOWN: case Common::EVENT_RBUTTONDOWN: case Common::EVENT_MOUSEMOVE: if (event.type == Common::EVENT_LBUTTONDOWN) _leftBtnPressed |= msClicked|msDown; else if (event.type == Common::EVENT_RBUTTONDOWN) _rightBtnPressed |= msClicked|msDown; _mouse.x = event.mouse.x; _mouse.y = event.mouse.y; if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) { _mouse.x -= (kHercWidth - _screenWidth * 2) / 2; _mouse.x >>= 1; _mouse.y = _mouse.y * 4 / 7; } else if (_useCJKMode && _textSurfaceMultiplier == 2) {
void CGEEngine::runGame() { if (_quitFlag) return; loadHeroXY(); _sceneLight->_flags._tran = true; _vga->_showQ->append(_sceneLight); _sceneLight->_flags._hide = false; const Seq pocSeq[] = { { 0, 0, 0, 0, 20 }, { 1, 2, 0, 0, 4 }, { 2, 3, 0, 0, 4 }, { 3, 4, 0, 0, 16 }, { 2, 5, 0, 0, 4 }, { 1, 6, 0, 0, 4 }, { 0, 1, 0, 0, 16 }, }; Seq *seq = (Seq *)malloc(7 * sizeof(Seq)); Common::copy(pocSeq, pocSeq + 7, seq); _pocLight->setSeq(seq); _pocLight->_flags._tran = true; _pocLight->_time = 1; _pocLight->_z = 120; _vga->_showQ->append(_pocLight); selectPocket(-1); _vga->_showQ->append(_mouse); loadUser(); if ((_sprite = _vga->_spareQ->locate(121)) != NULL) _commandHandlerTurbo->addCommand(kCmdSeq, -1, _vga->_mono, _sprite); if ((_sprite = _vga->_spareQ->locate(122)) != NULL) _sprite->step(_music); _commandHandlerTurbo->addCommand(kCmdSeq, -1, _music, _sprite); if (!_music) _midiPlayer->killMidi(); if (_resman->exist("MINI.SPR")) { _miniShp = new BitmapPtr[2]; _miniShp[0] = _miniShp[1] = NULL; loadSprite("MINI", -1, 0, kMiniX, kMiniY); expandSprite(_miniScene = _sprite); // NULL is ok if (_miniScene) { _miniScene->_flags._kill = false; _miniScene->_flags._hide = true; _miniShp[0] = new Bitmap(this, *_miniScene->shp()); _miniShpList = _miniScene->setShapeList(_miniShp); postMiniStep(-1); } } if (_hero) { expandSprite(_hero); _hero->gotoxy(_heroXY[_now - 1].x, _heroXY[_now - 1].y); if (_resman->exist("00SHADOW.SPR")) { loadSprite("00SHADOW", -1, 0, _hero->_x + 14, _hero->_y + 51); delete _shadow; if ((_shadow = _sprite) != NULL) { _shadow->_ref = 2; _shadow->_flags._tran = true; _shadow->_flags._kill = false; _hero->_flags._shad = true; _vga->_showQ->insert(_vga->_spareQ->remove(_shadow), _hero); } } } _infoLine->gotoxy(kInfoX, kInfoY); _infoLine->_flags._tran = true; _infoLine->update(NULL); _vga->_showQ->insert(_infoLine); _debugLine->_z = 126; _vga->_showQ->insert(_debugLine); if (_horzLine) { _horzLine->_y = kMapTop - (kMapTop > 0); _horzLine->_z = 126; _vga->_showQ->insert(_horzLine); } _mouse->_busy = _vga->_spareQ->locate(kBusyRef); if (_mouse->_busy) expandSprite(_mouse->_busy); _startupMode = 0; _commandHandler->addCommand(kCmdLevel, -1, _oldLev, &_sceneLight); _sceneLight->gotoxy(kSceneX + ((_now - 1) % kSceneNx) * kSceneDx + kSceneSX, kSceneY + ((_now - 1) / kSceneNx) * kSceneDy + kSceneSY); sceneUp(); _keyboard->setClient(_sys); // main loop while (!_endGame && !_quitFlag) { if (_flag[3]) // Flag FINIS _commandHandler->addCallback(kCmdExec, -1, 0, kQGame); mainLoop(); } // If finishing game due to closing ScummVM window, explicitly save the game if (!_endGame && canSaveGameStateCurrently()) qGame(); _keyboard->setClient(NULL); _commandHandler->addCommand(kCmdClear, -1, 0, NULL); _commandHandlerTurbo->addCommand(kCmdClear, -1, 0, NULL); _mouse->off(); _vga->_showQ->clear(); _vga->_spareQ->clear(); _hero = NULL; _shadow = NULL; }
void StarkEngine::processEvents() { Common::Event e; while (g_system->getEventManager()->pollEvent(e)) { // Handle any buttons, keys and joystick operations if (isPaused()) { // Only pressing key P to resume the game is allowed when the game is paused if (e.type == Common::EVENT_KEYDOWN && e.kbd.keycode == Common::KEYCODE_p) { pauseEngine(false); } continue; } if (e.type == Common::EVENT_KEYDOWN) { if (e.kbd.keycode == Common::KEYCODE_d) { if (e.kbd.flags & Common::KBD_CTRL) { _console->attach(); _console->onFrame(); } } else if (e.kbd.keycode == Common::KEYCODE_ESCAPE) { _userInterface->handleEscape(); } else if ((e.kbd.keycode == Common::KEYCODE_RETURN || e.kbd.keycode == Common::KEYCODE_KP_ENTER)) { if (e.kbd.hasFlags(Common::KBD_ALT)) { _gfx->toggleFullscreen(); } else if (_userInterface->isInGameScreen()){ _userInterface->selectFocusedDialogOption(); } } else if (e.kbd.keycode == Common::KEYCODE_F1) { _userInterface->toggleScreen(Screen::kScreenDiaryIndex); } else if (e.kbd.keycode == Common::KEYCODE_F2) { if (_userInterface->isInSaveLoadMenuScreen() || canSaveGameStateCurrently()) { _userInterface->toggleScreen(Screen::kScreenSaveMenu); } } else if (e.kbd.keycode == Common::KEYCODE_F3) { _userInterface->toggleScreen(Screen::kScreenLoadMenu); } else if (e.kbd.keycode == Common::KEYCODE_F4) { _userInterface->toggleScreen(Screen::kScreenDialog); } else if (e.kbd.keycode == Common::KEYCODE_F5) { if (_diary->isEnabled()) { _userInterface->toggleScreen(Screen::kScreenDiaryPages); } } else if (e.kbd.keycode == Common::KEYCODE_F6) { _userInterface->toggleScreen(Screen::kScreenFMVMenu); } else if (e.kbd.keycode == Common::KEYCODE_F7) { _userInterface->toggleScreen(Screen::kScreenSettingsMenu); } else if (e.kbd.keycode == Common::KEYCODE_F8) { warning("TODO: Implement the screenshot saving to local game directory"); } else if (e.kbd.keycode == Common::KEYCODE_F9) { if (_userInterface->isInGameScreen()) { _userInterface->requestToggleSubtitle(); } } else if (e.kbd.keycode == Common::KEYCODE_F10) { if (_userInterface->isInGameScreen() || _userInterface->isInDiaryIndexScreen()) { if (_userInterface->confirm(GameMessage::kQuitGamePrompt)) { _userInterface->requestQuitToMainMenu(); } } } else if (e.kbd.keycode == Common::KEYCODE_a) { if (_userInterface->isInGameScreen()) { _userInterface->cycleBackInventory(); } } else if (e.kbd.keycode == Common::KEYCODE_s) { if (_userInterface->isInGameScreen()) { _userInterface->cycleForwardInventory(); } } else if (e.kbd.keycode == Common::KEYCODE_i) { if (_userInterface->isInGameScreen()) { _userInterface->inventoryOpen(!_userInterface->isInventoryOpen()); } } else if (e.kbd.keycode == Common::KEYCODE_x && !e.kbd.hasFlags(Common::KBD_ALT)) { if (_userInterface->isInGameScreen()) { _userInterface->toggleExitDisplay(); } } else if ((e.kbd.keycode == Common::KEYCODE_x || e.kbd.keycode == Common::KEYCODE_q) && e.kbd.hasFlags(Common::KBD_ALT)) { if (_userInterface->confirm(GameMessage::kQuitPrompt)) { _userInterface->notifyShouldExit(); } } else if (e.kbd.keycode == Common::KEYCODE_p) { if (_userInterface->isInGameScreen()) { pauseEngine(true); debug("The game is paused"); } } else if (e.kbd.keycode == Common::KEYCODE_PAGEUP) { if (_userInterface->isInGameScreen()) { if (_userInterface->isInventoryOpen()) { _userInterface->scrollInventoryUp(); } else { _userInterface->scrollDialogUp(); } } } else if (e.kbd.keycode == Common::KEYCODE_UP) { if (_userInterface->isInGameScreen()) { if (_userInterface->isInventoryOpen()) { _userInterface->scrollInventoryUp(); } else { _userInterface->focusPrevDialogOption(); } } } else if (e.kbd.keycode == Common::KEYCODE_PAGEDOWN) { if (_userInterface->isInGameScreen()) { if (_userInterface->isInventoryOpen()) { _userInterface->scrollInventoryDown(); } else { _userInterface->scrollDialogDown(); } } } else if (e.kbd.keycode == Common::KEYCODE_DOWN) { if (_userInterface->isInGameScreen()) { if (_userInterface->isInventoryOpen()) { _userInterface->scrollInventoryDown(); } else { _userInterface->focusNextDialogOption(); } } } else if (e.kbd.keycode >= Common::KEYCODE_1 && e.kbd.keycode <= Common::KEYCODE_9) { if (_userInterface->isInGameScreen()) { _userInterface->selectDialogOptionByIndex(e.kbd.keycode - Common::KEYCODE_1); } } } else if (e.type == Common::EVENT_LBUTTONUP) { _userInterface->handleMouseUp(); } else if (e.type == Common::EVENT_MOUSEMOVE) { _userInterface->handleMouseMove(e.mouse); } else if (e.type == Common::EVENT_LBUTTONDOWN) { _userInterface->handleClick(); if (_system->getMillis() - _lastClickTime < _doubleClickDelay) { _userInterface->handleDoubleClick(); } _lastClickTime = _system->getMillis(); } else if (e.type == Common::EVENT_RBUTTONDOWN) { _userInterface->handleRightClick(); } else if (e.type == Common::EVENT_SCREEN_CHANGED) { _gfx->computeScreenViewport(); _fontProvider->initFonts(); _userInterface->onScreenChanged(); } } }