void DrasculaEngine::updateEvents() { Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); updateMusic(); #ifdef _WIN32_WCE if (eventMan->pollEvent(event)) { #else while (eventMan->pollEvent(event)) { #endif switch (event.type) { case Common::EVENT_KEYDOWN: addKeyToBuffer(event.kbd); break; case Common::EVENT_KEYUP: break; case Common::EVENT_MOUSEMOVE: mouseX = event.mouse.x; mouseY = event.mouse.y; break; case Common::EVENT_LBUTTONDOWN: leftMouseButton = 1; break; case Common::EVENT_LBUTTONUP: leftMouseButton = 0; break; case Common::EVENT_RBUTTONDOWN: // We changed semantic and react only on button up event break; case Common::EVENT_RBUTTONUP: rightMouseButton = 1; break; case Common::EVENT_QUIT: // TODO endChapter(); _system->quit(); break; default: break; } } } void DrasculaEngine::delay(int ms) { uint32 end = _system->getMillis() + ms * 2; // originally was 1 do { _system->delayMillis(10); updateEvents(); _system->updateScreen(); } while (_system->getMillis() < end); }
void DrasculaEngine::updateEvents() { Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); updateMusic(); #ifdef _WIN32_WCE if (eventMan->pollEvent(event)) { #else while (eventMan->pollEvent(event)) { #endif switch (event.type) { case Common::EVENT_KEYDOWN: if (event.kbd.keycode == Common::KEYCODE_d && event.kbd.hasFlags(Common::KBD_CTRL)) { // Start the debugger getDebugger()->attach(); getDebugger()->onFrame(); } addKeyToBuffer(event.kbd); break; case Common::EVENT_KEYUP: break; case Common::EVENT_MOUSEMOVE: _mouseX = event.mouse.x; _mouseY = event.mouse.y; break; case Common::EVENT_LBUTTONDOWN: _leftMouseButton = 1; break; case Common::EVENT_LBUTTONUP: _leftMouseButton = 0; break; case Common::EVENT_RBUTTONDOWN: // We changed semantic and react only on button up event break; case Common::EVENT_RBUTTONUP: _rightMouseButton = 1; break; default: break; } } } void DrasculaEngine::delay(int ms) { uint32 end = _system->getMillis() + ms * 2; // originally was 1 do { _system->delayMillis(10); updateEvents(); _system->updateScreen(); } while (_system->getMillis() < end && !shouldQuit()); }
void BladeRunnerEngine::handleEvents() { if (shouldQuit()) { _gameIsRunning = false; return; } Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_KEYUP: handleKeyUp(event); break; case Common::EVENT_KEYDOWN: handleKeyDown(event); break; case Common::EVENT_LBUTTONUP: handleMouseAction(event.mouse.x, event.mouse.y, true, false); break; case Common::EVENT_RBUTTONUP: case Common::EVENT_MBUTTONUP: handleMouseAction(event.mouse.x, event.mouse.y, false, false); break; case Common::EVENT_LBUTTONDOWN: handleMouseAction(event.mouse.x, event.mouse.y, true, true); break; case Common::EVENT_RBUTTONDOWN: case Common::EVENT_MBUTTONDOWN: handleMouseAction(event.mouse.x, event.mouse.y, false, true); break; default: ; // nothing to do } } }
void VideoPlayer::processVideoEvents(Common::List<Common::Event> &stopEvents) { Common::Event curEvent; Common::EventManager *eventMan = g_system->getEventManager(); // Process events, and skip video if esc is pressed while (eventMan->pollEvent(curEvent)) { if (curEvent.type == Common::EVENT_RTL || curEvent.type == Common::EVENT_QUIT) { _skipVideo = true; } for (Common::List<Common::Event>::const_iterator iter = stopEvents.begin(); iter != stopEvents.end(); iter++) { if (curEvent.type == iter->type) { if (iter->type == Common::EVENT_KEYDOWN || iter->type == Common::EVENT_KEYUP) { if (curEvent.kbd.keycode == iter->kbd.keycode) { _skipVideo = true; break; } } else { _skipVideo = true; break; } } } } }
char EventTests::keystrokeToChar() { Common::EventManager *eventMan = g_system->getEventManager(); bool quitLoop = false; Common::Event event; // handle all keybd events while (!quitLoop) { while (eventMan->pollEvent(event)) { // Quit if explicitly requested! if (Engine::shouldQuit()) { return 0; } switch (event.type) { case Common::EVENT_KEYDOWN: if (event.kbd.keycode == Common::KEYCODE_ESCAPE) { return 0; } for (int i = 0; i < ARRAYSIZE(keyCodeLUT); i++) { if (event.kbd.keycode == keyCodeLUT[i].code) { return keyCodeLUT[i].value; } } break; default: break; // Ignore other events } } } return 0; }
bool Intro::escDelay(uint32 msecs) { Common::EventManager *eventMan = _system->getEventManager(); Common::Event event; if (_relDelay == 0) // first call, init with system time _relDelay = (int32)_system->getMillis(); _relDelay += msecs; // now wait until _system->getMillis() >= _relDelay int32 nDelay = 0; do { while (eventMan->pollEvent(event)) { if (event.type == Common::EVENT_KEYDOWN) { if (event.kbd.keycode == Common::KEYCODE_ESCAPE) return false; } else if (event.type == Common::EVENT_QUIT || event.type == Common::EVENT_RTL) { return false; } } nDelay = _relDelay - _system->getMillis(); if (nDelay < 0) nDelay = 0; else if (nDelay > 20) nDelay = 20; _system->delayMillis(nDelay); _skyScreen->processSequence(); _system->updateScreen(); } while (nDelay == 20); return true; }
void MidiTests::waitForMusicToPlay(MidiParser *parser) { Common::EventManager *eventMan = g_system->getEventManager(); bool quitLoop = false; Common::Event event; CursorMan.showMouse(true); while (!quitLoop) { while (eventMan->pollEvent(event)) { // Quit if explicitly requested! if (Engine::shouldQuit()) { return; } if (event.type == Common::EVENT_LBUTTONDOWN || event.type == Common::EVENT_RBUTTONDOWN) { quitLoop = true; } else { Testsuite::writeOnScreen("Playing Midi Music, Click to end", Common::Point(0, 100)); if (!parser->isPlaying()) { quitLoop = true; } } } } CursorMan.showMouse(false); return; }
void MoviePlayer::handleNextFrame() { Common::Event event; Common::EventManager *eventMan = _vm->_system->getEventManager(); while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_KEYDOWN: if (event.kbd.keycode == Common::KEYCODE_ESCAPE) { _leftButtonDown = true; _rightButtonDown = true; } else if (event.kbd.keycode == Common::KEYCODE_PAUSE) { _vm->pause(); } break; case Common::EVENT_LBUTTONDOWN: _leftButtonDown = true; break; case Common::EVENT_RBUTTONDOWN: _rightButtonDown = true; break; case Common::EVENT_LBUTTONUP: _leftButtonDown = false; break; case Common::EVENT_RBUTTONUP: _rightButtonDown = false; break; default: break; } } if (_leftButtonDown && _rightButtonDown && !_vm->getBitFlag(41)) { _skipMovie = true; _mixer->stopHandle(_bgSound); } }
void NeverhoodEngine::mainLoop() { uint32 nextFrameTime = 0; while (!shouldQuit()) { Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_KEYDOWN: if (event.kbd.hasFlags(Common::KBD_CTRL) && event.kbd.keycode == Common::KEYCODE_d) { // Open debugger console _console->attach(); continue; } _gameModule->handleKeyDown(event.kbd.keycode); _gameModule->handleAsciiKey(event.kbd.ascii); break; case Common::EVENT_KEYUP: break; case Common::EVENT_MOUSEMOVE: _mouseX = event.mouse.x; _mouseY = event.mouse.y; _gameModule->handleMouseMove(event.mouse.x, event.mouse.y); break; case Common::EVENT_LBUTTONDOWN: case Common::EVENT_RBUTTONDOWN: _gameModule->handleMouseDown(event.mouse.x, event.mouse.y); break; case Common::EVENT_LBUTTONUP: case Common::EVENT_RBUTTONUP: _gameModule->handleMouseUp(event.mouse.x, event.mouse.y); break; case Common::EVENT_WHEELUP: _gameModule->handleWheelUp(); break; case Common::EVENT_WHEELDOWN: _gameModule->handleWheelDown(); break; default: break; } } if (_system->getMillis() >= nextFrameTime) { _gameModule->checkRequests(); _gameModule->handleUpdate(); _gameModule->draw(); _console->onFrame(); _screen->update(); if (_updateSound) _soundMan->update(); nextFrameTime = _screen->getNextFrameTime(); }; _audioResourceMan->updateMusic(); _system->updateScreen(); _system->delayMillis(10); } }
void Journal::use() { BobSlot *joe = _vm->graphics()->bob(0); _prevJoeX = joe->x; _prevJoeY = joe->y; _panelMode = PM_NORMAL; _system = g_system; _panelTextCount = 0; memset(_panelTextY, 0, sizeof(_panelTextY)); memset(&_textField, 0, sizeof(_textField)); memset(_saveDescriptions, 0, sizeof(_saveDescriptions)); _vm->findGameStateDescriptions(_saveDescriptions); setup(); redraw(); update(); _vm->display()->palFadeIn(ROOM_JOURNAL); _quitMode = QM_LOOP; while (_quitMode == QM_LOOP) { Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_KEYDOWN: handleKeyDown(event.kbd.ascii, event.kbd.keycode); break; case Common::EVENT_LBUTTONDOWN: handleMouseDown(event.mouse.x, event.mouse.y); break; case Common::EVENT_WHEELUP: handleMouseWheel(-1); break; case Common::EVENT_WHEELDOWN: handleMouseWheel(1); break; case Common::EVENT_RTL: case Common::EVENT_QUIT: return; default: break; } } _system->delayMillis(20); _system->updateScreen(); } _vm->writeOptionSettings(); _vm->display()->clearTexts(0, GAME_SCREEN_HEIGHT - 1); _vm->graphics()->putCameraOnBob(0); if (_quitMode == QM_CONTINUE) { continueGame(); } }
static int eatSystemEvents() { Common::Event event; Common::EventManager *eventMan = g_system->getEventManager(); while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_QUIT: return 1; default: break; } } return 0; }
void MadeEngine::handleEvents() { Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); // NOTE: Don't reset _eventNum to 0 here or no events will get through to the scripts. while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_MOUSEMOVE: _eventMouseX = event.mouse.x; _eventMouseY = event.mouse.y; break; case Common::EVENT_LBUTTONDOWN: _eventNum = 2; break; case Common::EVENT_LBUTTONUP: _eventNum = 1; break; case Common::EVENT_RBUTTONDOWN: _eventNum = 4; break; case Common::EVENT_RBUTTONUP: _eventNum = 3; break; case Common::EVENT_KEYDOWN: _eventKey = event.kbd.ascii; // For unknown reasons, the game accepts ASCII code // 9 as backspace if (_eventKey == Common::KEYCODE_BACKSPACE) _eventKey = 9; _eventNum = 5; break; default: break; } } AudioCD.updateCD(); }
void manageEvents() { Common::EventManager *eventMan = g_system->getEventManager(); uint32 nextFrame = g_system->getMillis() + g_cine->getTimerDelay(); do { Common::Event event; while (eventMan->pollEvent(event)) { processEvent(event); } g_system->updateScreen(); g_system->delayMillis(20); } while (g_system->getMillis() < nextFrame); mouseData.left = mouseLeft; mouseData.right = mouseRight; }
void NeverhoodEngine::mainLoop() { uint32 nextFrameTime = 0; while (!shouldQuit()) { Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_KEYDOWN: _gameModule->handleKeyDown(event.kbd.keycode); _gameModule->handleAsciiKey(event.kbd.ascii); break; case Common::EVENT_KEYUP: break; case Common::EVENT_MOUSEMOVE: _mouseX = event.mouse.x; _mouseY = event.mouse.y; _gameModule->handleMouseMove(event.mouse.x, event.mouse.y); break; case Common::EVENT_LBUTTONDOWN: case Common::EVENT_RBUTTONDOWN: _gameModule->handleMouseDown(event.mouse.x, event.mouse.y); break; case Common::EVENT_LBUTTONUP: case Common::EVENT_RBUTTONUP: _gameModule->handleMouseUp(event.mouse.x, event.mouse.y); break; case Common::EVENT_QUIT: _system->quit(); break; default: break; } } if (_system->getMillis() >= nextFrameTime) { _gameModule->checkRequests(); _gameModule->handleUpdate(); _gameModule->draw(); _screen->update(); nextFrameTime = _screen->getNextFrameTime(); }; _soundMan->update(); _audioResourceMan->updateMusic(); _system->updateScreen(); _system->delayMillis(10); } }
void VirtualKeyboardGUI::mainLoop() { Common::EventManager *eventMan = _system->getEventManager(); while (_displaying) { if (_kbd->_keyQueue.hasStringChanged()) updateDisplay(); animateCaret(); animateCursor(); redraw(); _system->updateScreen(); Common::Event event; while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_LBUTTONDOWN: if (_kbdBound.contains(event.mouse)) { _kbd->handleMouseDown(event.mouse.x - _kbdBound.left, event.mouse.y - _kbdBound.top); } break; case Common::EVENT_LBUTTONUP: if (_kbdBound.contains(event.mouse)) { _kbd->handleMouseUp(event.mouse.x - _kbdBound.left, event.mouse.y - _kbdBound.top); } break; case Common::EVENT_MOUSEMOVE: if (_drag) move(event.mouse.x - _dragPoint.x, event.mouse.y - _dragPoint.y); break; case Common::EVENT_SCREEN_CHANGED: screenChanged(); break; case Common::EVENT_QUIT: _system->quit(); return; default: break; } } // Delay for a moment _system->delayMillis(10); } }
// TODO: this method will probably go away and be integrated in the main loop void Animation::play() { Common::EventManager *eventMan = g_system->getEventManager(); while (!hasEnded() && !Engine::shouldQuit()) { process(); if (_changed) { // Create a temporary surface to merge the overlay with the background Graphics::Surface *s = new Graphics::Surface; s->create(640, 480, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)); draw(s); // XXX: Update the screen g_system->copyRectToScreen(s->getPixels(), s->pitch, 0, 0, s->w, s->h); // Free the temporary surface s->free(); delete s; _changed = false; } g_system->updateScreen(); //FIXME: implement subtitles g_system->delayMillis(20); // Handle right-click to interrupt animations Common::Event ev = Common::Event(); while (eventMan->pollEvent(ev)) { if (ev.type == Common::EVENT_RBUTTONUP) { // Stop audio if (_audio) _audio->finish(); // TODO start LNK file sound? return; } } } }
bool MoviePlayer::handleInput() { Common::Event event; Common::EventManager *eventMan = g_system->getEventManager(); while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_KEYDOWN: if (event.kbd.keycode == Common::KEYCODE_ESCAPE) return false; break; case Common::EVENT_LBUTTONDOWN: case Common::EVENT_RBUTTONDOWN: return false; case Common::EVENT_QUIT: _vm->quitGame(); return false; default: break; } } return !_vm->shouldQuit(); }
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(); }
void MenuSystem::handleEvents() { Common::Event event; Common::EventManager *eventMan = _vm->_system->getEventManager(); while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_KEYDOWN: handleKeyDown(event.kbd); break; case Common::EVENT_QUIT: _running = false; break; case Common::EVENT_MOUSEMOVE: handleMouseMove(event.mouse.x, event.mouse.y); break; case Common::EVENT_LBUTTONUP: handleMouseClick(event.mouse.x, event.mouse.y); break; default: break; } } }
bool MoviePlayer::handleInput() { Common::Event event; Common::EventManager *eventMan = g_system->getEventManager(); while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_KEYDOWN: if (event.kbd.keycode == Common::KEYCODE_ESCAPE) return false; if (event.kbd.keycode == Common::KEYCODE_F10) { // TODO: The original would bring up a stripped down // main menu dialog, without the save/restore options. } break; case Common::EVENT_LBUTTONDOWN: case Common::EVENT_RBUTTONDOWN: return false; case Common::EVENT_QUIT: return false; default: break; } } return !_vm->shouldQuit(); }
bool MainMenu::getInput() { Common::Event event; Common::EventManager *eventMan = _vm->getEventManager(); bool updateScreen = false; while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_LBUTTONUP: return true; case Common::EVENT_MOUSEMOVE: updateScreen = true; break; default: break; } } if (updateScreen) _system->updateScreen(); return false; }
void MadeEngine::handleEvents() { Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); // NOTE: Don't reset _eventNum to 0 here or no events will get through to the scripts. while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_MOUSEMOVE: _eventMouseX = event.mouse.x; _eventMouseY = event.mouse.y; break; case Common::EVENT_LBUTTONDOWN: _eventNum = 2; break; case Common::EVENT_LBUTTONUP: _eventNum = 1; break; case Common::EVENT_RBUTTONDOWN: _eventNum = 4; break; case Common::EVENT_RBUTTONUP: _eventNum = 3; break; case Common::EVENT_KEYDOWN: // Handle any special keys here // Supported keys taken from http://www.allgame.com/game.php?id=13542&tab=controls switch (event.kbd.keycode) { case Common::KEYCODE_KP_PLUS: // action (same as left mouse click) _eventNum = 1; // left mouse button up break; case Common::KEYCODE_KP_MINUS: // inventory (same as right mouse click) _eventNum = 3; // right mouse button up break; case Common::KEYCODE_UP: case Common::KEYCODE_KP8: _eventMouseY = MAX<int16>(0, _eventMouseY - 1); g_system->warpMouse(_eventMouseX, _eventMouseY); break; case Common::KEYCODE_DOWN: case Common::KEYCODE_KP2: _eventMouseY = MIN<int16>(199, _eventMouseY + 1); g_system->warpMouse(_eventMouseX, _eventMouseY); break; case Common::KEYCODE_LEFT: case Common::KEYCODE_KP4: _eventMouseX = MAX<int16>(0, _eventMouseX - 1); g_system->warpMouse(_eventMouseX, _eventMouseY); break; case Common::KEYCODE_RIGHT: case Common::KEYCODE_KP6: _eventMouseX = MIN<int16>(319, _eventMouseX + 1); g_system->warpMouse(_eventMouseX, _eventMouseY); break; case Common::KEYCODE_F1: // menu case Common::KEYCODE_F2: // save game case Common::KEYCODE_F3: // load game case Common::KEYCODE_F4: // repeat last message _eventNum = 5; _eventKey = (event.kbd.keycode - Common::KEYCODE_F1) + 21; break; case Common::KEYCODE_BACKSPACE: _eventNum = 5; _eventKey = 9; break; default: _eventNum = 5; _eventKey = event.kbd.ascii; break; } // Check for Debugger Activation if (event.kbd.hasFlags(Common::KBD_CTRL) && event.kbd.keycode == Common::KEYCODE_d) { this->getDebugger()->attach(); this->getDebugger()->onFrame(); } break; default: break; } } _system->getAudioCDManager()->updateCD(); }
void GuiManager::runLoop() { Dialog * const activeDialog = getTopDialog(); bool didSaveState = false; int button; uint32 time; if (activeDialog == 0) return; if (!_stateIsSaved) { saveState(); _theme->enable(); didSaveState = true; _useStdCursor = !_theme->ownCursor(); if (_useStdCursor) setupCursor(); // _theme->refresh(); _redrawStatus = kRedrawFull; redraw(); } _lastMousePosition.x = _lastMousePosition.y = -1; _lastMousePosition.time = 0; Common::EventManager *eventMan = _system->getEventManager(); uint32 lastRedraw = 0; const uint32 waitTime = 1000 / 45; bool tooltipCheck = false; while (!_dialogStack.empty() && activeDialog == getTopDialog() && !eventMan->shouldQuit()) { redraw(); // Don't "tickle" the dialog until the theme has had a chance // to re-allocate buffers in case of a scaler change. activeDialog->handleTickle(); if (_useStdCursor) animateCursor(); // _theme->updateScreen(); // _system->updateScreen(); if (lastRedraw + waitTime < _system->getMillis()) { _theme->updateScreen(); _system->updateScreen(); lastRedraw = _system->getMillis(); } Common::Event event; while (eventMan->pollEvent(event)) { // The top dialog can change during the event loop. In that case, flush all the // dialog-related events since they were probably generated while the old dialog // was still visible, and therefore not intended for the new one. // // This hopefully fixes strange behavior/crashes with pop-up widgets. (Most easily // triggered in 3x mode or when running ScummVM under Valgrind.) if (activeDialog != getTopDialog() && event.type != Common::EVENT_SCREEN_CHANGED) continue; Common::Point mouse(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y); switch (event.type) { case Common::EVENT_KEYDOWN: activeDialog->handleKeyDown(event.kbd); break; case Common::EVENT_KEYUP: activeDialog->handleKeyUp(event.kbd); break; case Common::EVENT_MOUSEMOVE: activeDialog->handleMouseMoved(mouse.x, mouse.y, 0); if (mouse.x != _lastMousePosition.x || mouse.y != _lastMousePosition.y) { _lastMousePosition.x = mouse.x; _lastMousePosition.y = mouse.y; _lastMousePosition.time = _system->getMillis(); } tooltipCheck = true; break; // We don't distinguish between mousebuttons (for now at least) case Common::EVENT_LBUTTONDOWN: case Common::EVENT_RBUTTONDOWN: button = (event.type == Common::EVENT_LBUTTONDOWN ? 1 : 2); time = _system->getMillis(); if (_lastClick.count && (time < _lastClick.time + kDoubleClickDelay) && ABS(_lastClick.x - event.mouse.x) < 3 && ABS(_lastClick.y - event.mouse.y) < 3) { _lastClick.count++; } else { _lastClick.x = event.mouse.x; _lastClick.y = event.mouse.y; _lastClick.count = 1; } _lastClick.time = time; activeDialog->handleMouseDown(mouse.x, mouse.y, button, _lastClick.count); break; case Common::EVENT_LBUTTONUP: case Common::EVENT_RBUTTONUP: button = (event.type == Common::EVENT_LBUTTONUP ? 1 : 2); activeDialog->handleMouseUp(mouse.x, mouse.y, button, _lastClick.count); break; case Common::EVENT_WHEELUP: activeDialog->handleMouseWheel(mouse.x, mouse.y, -1); break; case Common::EVENT_WHEELDOWN: activeDialog->handleMouseWheel(mouse.x, mouse.y, 1); break; case Common::EVENT_SCREEN_CHANGED: screenChange(); break; default: #ifdef ENABLE_KEYMAPPER activeDialog->handleOtherEvent(event); #endif break; } if (lastRedraw + waitTime < _system->getMillis()) { _theme->updateScreen(); _system->updateScreen(); lastRedraw = _system->getMillis(); } } if (tooltipCheck && _lastMousePosition.time + kTooltipDelay < _system->getMillis()) { Widget *wdg = activeDialog->findWidget(_lastMousePosition.x, _lastMousePosition.y); if (wdg && wdg->getTooltip()) { Tooltip *tooltip = new Tooltip(); tooltip->setup(activeDialog, wdg, _lastMousePosition.x, _lastMousePosition.y); tooltip->runModal(); delete tooltip; } } // Delay for a moment _system->delayMillis(10); } // WORKAROUND: When quitting we might not properly close the dialogs on // the dialog stack, thus we do this here to avoid any problems. // This is most noticable in bug #3481395 "LAUNCHER: Can't quit from unsupported game dialog". // It seems that Dialog::runModal never removes the dialog from the dialog // stack, thus if the dialog does not call Dialog::close to close itself // it will never be removed. Since we can have multiple run loops being // called we cannot rely on catching EVENT_QUIT in the event loop above, // since it would only catch it for the top run loop. if (eventMan->shouldQuit() && activeDialog == getTopDialog()) getTopDialog()->close(); if (didSaveState) { _theme->disable(); restoreState(); _useStdCursor = false; } }
void Util::processInput(bool scroll) { Common::Event event; Common::EventManager *eventMan = g_system->getEventManager(); int16 x = 0, y = 0; bool hasMove = false; _vm->_vidPlayer->updateLive(); while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_MOUSEMOVE: hasMove = true; x = event.mouse.x; y = event.mouse.y; break; case Common::EVENT_LBUTTONDOWN: _mouseButtons = (MouseButtons) (((uint32) _mouseButtons) | ((uint32) kMouseButtonsLeft)); break; case Common::EVENT_RBUTTONDOWN: _mouseButtons = (MouseButtons) (((uint32) _mouseButtons) | ((uint32) kMouseButtonsRight)); break; case Common::EVENT_LBUTTONUP: _mouseButtons = (MouseButtons) (((uint32) _mouseButtons) & ~((uint32) kMouseButtonsLeft)); break; case Common::EVENT_RBUTTONUP: _mouseButtons = (MouseButtons) (((uint32) _mouseButtons) & ~((uint32) kMouseButtonsRight)); break; case Common::EVENT_KEYDOWN: if (event.kbd.hasFlags(Common::KBD_CTRL)) { if (event.kbd.keycode == Common::KEYCODE_f) _fastMode ^= 1; else if (event.kbd.keycode == Common::KEYCODE_g) _fastMode ^= 2; else if (event.kbd.keycode == Common::KEYCODE_p) _vm->pauseGame(); else if (event.kbd.keycode == Common::KEYCODE_d) { _vm->getDebugger()->attach(); _vm->getDebugger()->onFrame(); } break; } addKeyToBuffer(event.kbd); break; case Common::EVENT_KEYUP: break; default: break; } } _vm->_global->_speedFactor = MIN(_fastMode + 1, 3); if (hasMove && scroll) { x = CLIP(x, _vm->_global->_mouseMinX, _vm->_global->_mouseMaxX); y = CLIP(y, _vm->_global->_mouseMinY, _vm->_global->_mouseMaxY); x -= _vm->_video->_screenDeltaX; y -= _vm->_video->_screenDeltaY; _vm->_util->setMousePos(x, y); _vm->_game->wantScroll(x, y); // WORKAROUND: // Force a check of the mouse in order to fix the sofa bug. This apply only for Gob3, and only // in the impacted TOT file so that the second screen animation is not broken. if ((_vm->getGameType() == kGameTypeGob3) && !scumm_stricmp(_vm->_game->_curTotFile, "EMAP1008.TOT")) _vm->_game->evaluateScroll(); } }
static sci_event_t scummvm_get_event(struct _gfx_driver *drv) { sci_event_t input; input.type = SCI_EVT_NONE; Common::EventManager *em = g_system->getEventManager(); Common::Event ev; bool found = em->pollEvent(ev); Common::Point p = ev.mouse; // Don't generate events for mouse movement while (found && ev.type == Common::EVENT_MOUSEMOVE) { found = em->pollEvent(ev); p = ev.mouse; drv->pointer_x = p.x; drv->pointer_y = p.y; S->update_mouse = true; } // Update the screen here, since it's called very often if (S->update_mouse) g_system->warpMouse(drv->pointer_x, drv->pointer_y); if (S->update_screen || S->update_mouse) { g_system->updateScreen(); S->update_screen = false; S->update_mouse = false; } if (found && !ev.synthetic && ev.type != Common::EVENT_MOUSEMOVE) { int modifiers; if (ev.type == Common::EVENT_KEYDOWN) modifiers = ev.kbd.flags; else modifiers = em->getModifierState(); input.buckybits = ((modifiers & Common::KBD_ALT) ? SCI_EVM_ALT : 0) | ((modifiers & Common::KBD_CTRL) ? SCI_EVM_CTRL : 0) | ((modifiers & Common::KBD_SHIFT) ? SCI_EVM_LSHIFT | SCI_EVM_RSHIFT : 0); //TODO: SCI_EVM_SCRLOCK SCI_EVM_NUMLOCK SCI_EVM_CAPSLOCK SCI_EVM_INSERT switch (ev.type) { // Keyboard events case Common::EVENT_KEYDOWN: input.data = ev.kbd.keycode; input.character = ev.kbd.ascii; if (!(input.data & 0xFF00)) { // Directly accept most common keys without conversion input.type = SCI_EVT_KEYBOARD; if (input.data == Common::KEYCODE_TAB) { // Tab input.type = SCI_EVT_KEYBOARD; input.data = SCI_K_TAB; if (input.buckybits & (SCI_EVM_LSHIFT | SCI_EVM_RSHIFT)) input.character = SCI_K_SHIFT_TAB; else input.character = SCI_K_TAB; } } else if ((input.data >= Common::KEYCODE_F1) && input.data <= Common::KEYCODE_F10) { // F1-F10 input.type = SCI_EVT_KEYBOARD; // SCI_K_F1 == 59 << 8 // SCI_K_SHIFT_F1 == 84 << 8 input.data = (input.data - Common::KEYCODE_F1 + SCI_K_F1) << 8; if (input.buckybits & (SCI_EVM_LSHIFT | SCI_EVM_RSHIFT)) input.character = input.data + ((SCI_K_SHIFT_F1 - SCI_K_F1) << 8); else input.character = input.data; } else { // Special keys that need conversion input.type = SCI_EVT_KEYBOARD; switch (ev.kbd.keycode) { case Common::KEYCODE_UP: input.data = SCI_K_UP; break; case Common::KEYCODE_DOWN: input.data = SCI_K_DOWN; break; case Common::KEYCODE_RIGHT: input.data = SCI_K_RIGHT; break; case Common::KEYCODE_LEFT: input.data = SCI_K_LEFT; break; case Common::KEYCODE_INSERT: input.data = SCI_K_INSERT; break; case Common::KEYCODE_HOME: input.data = SCI_K_HOME; break; case Common::KEYCODE_END: input.data = SCI_K_END; break; case Common::KEYCODE_PAGEUP: input.data = SCI_K_PGUP; break; case Common::KEYCODE_PAGEDOWN: input.data = SCI_K_PGDOWN; break; case Common::KEYCODE_DELETE: input.data = SCI_K_DELETE; break; //TODO: SCI_K_CENTER default: input.type = SCI_EVT_NONE; break; } input.character = input.data; } break; // Mouse events case Common::EVENT_LBUTTONDOWN: input.type = SCI_EVT_MOUSE_PRESS; input.data = 1; drv->pointer_x = p.x; drv->pointer_y = p.y; break; case Common::EVENT_RBUTTONDOWN: input.type = SCI_EVT_MOUSE_PRESS; input.data = 2; drv->pointer_x = p.x; drv->pointer_y = p.y; break; case Common::EVENT_LBUTTONUP: input.type = SCI_EVT_MOUSE_RELEASE; input.data = 1; drv->pointer_x = p.x; drv->pointer_y = p.y; break; case Common::EVENT_RBUTTONUP: input.type = SCI_EVT_MOUSE_RELEASE; input.data = 2; drv->pointer_x = p.x; drv->pointer_y = p.y; break; // Misc events case Common::EVENT_QUIT: input.type = SCI_EVT_QUIT; break; } } return input; }
void GuiManager::runLoop() { Dialog *activeDialog = getTopDialog(); bool didSaveState = false; int button; uint32 time; if (activeDialog == 0) return; if (!_stateIsSaved) { saveState(); _theme->enable(); didSaveState = true; _useStdCursor = !_theme->ownCursor(); if (_useStdCursor) setupCursor(); // _theme->refresh(); _redrawStatus = kRedrawFull; redraw(); } Common::EventManager *eventMan = _system->getEventManager(); uint32 lastRedraw = 0; const uint32 waitTime = 1000 / 45; #ifdef ENABLE_KEYMAPPER // Due to circular reference with event manager and GUI // we cannot init keymap on the GUI creation. Thus, let's // try to do it on every launch, checking whether the // map is already existing initKeymap(); eventMan->getKeymapper()->pushKeymap("gui"); #endif while (!_dialogStack.empty() && activeDialog == getTopDialog()) { redraw(); // Don't "tickle" the dialog until the theme has had a chance // to re-allocate buffers in case of a scaler change. activeDialog->handleTickle(); if (_useStdCursor) animateCursor(); // _theme->updateScreen(); // _system->updateScreen(); if (lastRedraw + waitTime < _system->getMillis()) { _theme->updateScreen(); _system->updateScreen(); lastRedraw = _system->getMillis(); } Common::Event event; while (eventMan->pollEvent(event)) { // The top dialog can change during the event loop. In that case, flush all the // dialog-related events since they were probably generated while the old dialog // was still visible, and therefore not intended for the new one. // // This hopefully fixes strange behaviour/crashes with pop-up widgets. (Most easily // triggered in 3x mode or when running ScummVM under Valgrind.) if (activeDialog != getTopDialog() && event.type != Common::EVENT_SCREEN_CHANGED) continue; Common::Point mouse(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y); if (lastRedraw + waitTime < _system->getMillis()) { _theme->updateScreen(); _system->updateScreen(); lastRedraw = _system->getMillis(); } switch (event.type) { case Common::EVENT_KEYDOWN: activeDialog->handleKeyDown(event.kbd); break; case Common::EVENT_KEYUP: activeDialog->handleKeyUp(event.kbd); break; case Common::EVENT_MOUSEMOVE: activeDialog->handleMouseMoved(mouse.x, mouse.y, 0); break; // We don't distinguish between mousebuttons (for now at least) case Common::EVENT_LBUTTONDOWN: case Common::EVENT_RBUTTONDOWN: button = (event.type == Common::EVENT_LBUTTONDOWN ? 1 : 2); time = _system->getMillis(); if (_lastClick.count && (time < _lastClick.time + kDoubleClickDelay) && ABS(_lastClick.x - event.mouse.x) < 3 && ABS(_lastClick.y - event.mouse.y) < 3) { _lastClick.count++; } else { _lastClick.x = event.mouse.x; _lastClick.y = event.mouse.y; _lastClick.count = 1; } _lastClick.time = time; activeDialog->handleMouseDown(mouse.x, mouse.y, button, _lastClick.count); break; case Common::EVENT_LBUTTONUP: case Common::EVENT_RBUTTONUP: button = (event.type == Common::EVENT_LBUTTONUP ? 1 : 2); activeDialog->handleMouseUp(mouse.x, mouse.y, button, _lastClick.count); break; case Common::EVENT_WHEELUP: activeDialog->handleMouseWheel(mouse.x, mouse.y, -1); break; case Common::EVENT_WHEELDOWN: activeDialog->handleMouseWheel(mouse.x, mouse.y, 1); break; case Common::EVENT_QUIT: return; case Common::EVENT_SCREEN_CHANGED: screenChange(); break; default: break; } } // Delay for a moment _system->delayMillis(10); } #ifdef ENABLE_KEYMAPPER eventMan->getKeymapper()->popKeymap(); #endif if (didSaveState) { _theme->disable(); restoreState(); _useStdCursor = false; } }
void FullpipeEngine::updateEvents() { Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); ExCommand *ex; while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_KEYDOWN: _keyState = event.kbd.keycode; switch (event.kbd.keycode) { case Common::KEYCODE_SPACE: if (_gamePaused) { if (_modalObject) { if (_modalObject->init(42)) { _modalObject->update(); } else { _modalObject->saveload(); BaseModalObject *obj = _modalObject->_parentObj; if (obj) delete _modalObject; _modalObject = obj; } } else { _gameLoader->updateSystems(42); } return; } ex = new ExCommand(0, 17, 36, 0, 0, 0, 1, 0, 0, 0); ex->_keyCode = 32; ex->_excFlags |= 3; ex->handle(); break; case Common::KEYCODE_s: if (_gamePaused) { _gamePaused = 0; _flgGameIsRunning = true; return; } ex = new ExCommand(0, 17, 36, 0, 0, 0, 1, 0, 0, 0); ex->_keyCode = event.kbd.keycode; ex->_excFlags |= 3; ex->handle(); break; case Common::KEYCODE_q: return; break; default: if (event.kbd.keycode == Common::KEYCODE_d && event.kbd.hasFlags(Common::KBD_CTRL)) { // Start the debugger getDebugger()->attach(); getDebugger()->onFrame(); } ex = new ExCommand(0, 17, 36, 0, 0, 0, 1, 0, 0, 0); ex->_keyCode = event.kbd.keycode; ex->_excFlags |= 3; ex->handle(); break; } break; case Common::EVENT_KEYUP: if (!_inputArFlag) { ex = new ExCommand(0, 17, 37, 0, 0, 0, 1, 0, 0, 0); ex->_excFlags |= 3; ex->handle(); } _keyState = Common::KEYCODE_INVALID; break; case Common::EVENT_MOUSEMOVE: if (_recordEvents) { ex = new ExCommand(0, 17, 31, event.mouse.x, event.mouse.y, 0, 1, 0, 0, 0); ex->_excFlags |= 3; ex->handle(); } _mouseScreenPos = event.mouse; break; case Common::EVENT_QUIT: _gameContinue = false; break; case Common::EVENT_RBUTTONDOWN: if (!_inputArFlag && (_updateTicks - _lastInputTicks) >= 2) { ex = new ExCommand(0, 17, 107, event.mouse.x, event.mouse.y, 0, 1, 0, 0, 0); ex->_excFlags |= 3; _lastInputTicks = _updateTicks; ex->handle(); } break; case Common::EVENT_LBUTTONDOWN: if (!_inputArFlag && (_updateTicks - _lastInputTicks) >= 2) { ex = new ExCommand(0, 17, 29, event.mouse.x, event.mouse.y, 0, 1, 0, 0, 0); ex->_sceneClickX = _sceneRect.left + ex->_x; ex->_sceneClickY = _sceneRect.top + ex->_y; ex->_keyCode = getGameLoaderInventory()->getSelectedItemId(); ex->_excFlags |= 3; _lastInputTicks = _updateTicks; ex->handle(); } break; case Common::EVENT_LBUTTONUP: if (!_inputArFlag && (_updateTicks - _lastButtonUpTicks) >= 2) { ex = new ExCommand(0, 17, 30, 0, 0, 0, 1, 0, 0, 0); ex->_excFlags |= 3; _lastButtonUpTicks = _updateTicks; ex->handle(); } break; default: break; } } // pollEvent() is implemented only for video player. So skip it. //if (event.kbd.keycode == MSG_SC11_SHOWSWING && _modalObject) { // _modalObject->pollEvent(); //} }
TestExitStatus EventTests::mouseEvents() { Testsuite::clearScreen(); Common::String info = "Testing Mouse events.\n " "Any movement/click generated by L/R/M mouse buttons or the mouse wheel should be detected.\n" "Press X to exit"; if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : keyboard events\n"); return kTestSkipped; } Common::EventManager *eventMan = g_system->getEventManager(); Common::Point pt(0, 30); Common::Rect rectInfo = Testsuite::writeOnScreen("Generate mouse events make L/R/M button clicks, move wheel", pt); pt.y += 15; Testsuite::writeOnScreen("Press X to exit", pt); pt.y = 70; Common::Rect rectLB = Testsuite::writeOnScreen("Left-button click : Not tested", pt); pt.y += 15; Common::Rect rectRB = Testsuite::writeOnScreen("Right-button click : Not tested", pt); pt.y += 15; Common::Rect rectMB = Testsuite::writeOnScreen("Middle-button click : Not tested", pt); pt.y += 15; Common::Rect rectWheel = Testsuite::writeOnScreen("Wheel Movements : Not tested", pt); // Init Mouse Palette GFXtests::initMousePalette(); Common::Rect finishZone = drawFinishZone(); bool quitLoop = false; TestExitStatus passed = kTestPassed; // handle all mouse events Common::Event event; while (!quitLoop) { // Show mouse CursorMan.showMouse(true); g_system->updateScreen(); while (eventMan->pollEvent(event)) { // Quit if explicitly requested if (Engine::shouldQuit()) { return passed; } switch (event.type) { case Common::EVENT_MOUSEMOVE: // Movements havee already been tested in GFX break; case Common::EVENT_LBUTTONDOWN: Testsuite::clearScreen(rectInfo); Testsuite::writeOnScreen("Mouse left-button pressed", Common::Point(rectInfo.left, rectInfo.top)); break; case Common::EVENT_RBUTTONDOWN: Testsuite::clearScreen(rectInfo); Testsuite::writeOnScreen("Mouse right-button pressed", Common::Point(rectInfo.left, rectInfo.top)); break; case Common::EVENT_WHEELDOWN: Testsuite::clearScreen(rectInfo); Testsuite::writeOnScreen("Mouse wheel moved down", Common::Point(rectInfo.left, rectInfo.top)); Testsuite::writeOnScreen("Wheel Movements : Done!", Common::Point(rectWheel.left, rectWheel.top)); break; case Common::EVENT_MBUTTONDOWN: Testsuite::clearScreen(rectInfo); Testsuite::writeOnScreen("Mouse middle-button pressed ", Common::Point(rectInfo.left, rectInfo.top)); break; case Common::EVENT_LBUTTONUP: Testsuite::clearScreen(rectInfo); if (finishZone.contains(eventMan->getMousePos())) { quitLoop = true; } Testsuite::writeOnScreen("Mouse left-button released", Common::Point(rectInfo.left, rectInfo.top)); Testsuite::writeOnScreen("Left-button clicks : Done!", Common::Point(rectLB.left, rectLB.top)); break; case Common::EVENT_RBUTTONUP: Testsuite::clearScreen(rectInfo); Testsuite::writeOnScreen("Mouse right-button released", Common::Point(rectInfo.left, rectInfo.top)); Testsuite::writeOnScreen("Right-button clicks : Done!", Common::Point(rectRB.left, rectRB.top)); break; case Common::EVENT_WHEELUP: Testsuite::clearScreen(rectInfo); Testsuite::writeOnScreen("Mouse wheel moved up", Common::Point(rectInfo.left, rectInfo.top)); Testsuite::writeOnScreen("Wheel Movements : Done!", Common::Point(rectWheel.left, rectWheel.top)); break; case Common::EVENT_MBUTTONUP: Testsuite::clearScreen(rectInfo); Testsuite::writeOnScreen("Mouse middle-button released ", Common::Point(rectInfo.left, rectInfo.top)); Testsuite::writeOnScreen("Middle-button clicks : Done!", Common::Point(rectMB.left, rectMB.top)); break; case Common::EVENT_KEYDOWN: if (event.kbd.keycode == Common::KEYCODE_x) { Testsuite::clearScreen(rectInfo); Testsuite::writeOnScreen("Exit requested", Common::Point(rectInfo.left, rectInfo.top)); quitLoop = true; } break; default: break; } } } CursorMan.showMouse(false); // Verify results now! if (Testsuite::handleInteractiveInput("Were mouse clicks (L/R/M buttons) and wheel movements identfied ?", "Yes", "No", kOptionRight)) { Testsuite::logDetailedPrintf("Mouse clicks (L/R/M buttons) and wheel movements failed"); passed = kTestFailed; } return passed; }
void FullpipeEngine::updateEvents() { Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); ExCommand *ex; while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_KEYDOWN: _keyState = event.kbd.keycode; switch (event.kbd.keycode) { case Common::KEYCODE_SPACE: if (_gamePaused) { if (_modalObject) { if (_modalObject->init(42)) { _modalObject->update(); } else { _modalObject->saveload(); BaseModalObject *obj = _modalObject->_parentObj; if (obj) delete _modalObject; _modalObject = obj; } } else { _gameLoader->updateSystems(42); } return; } ex = new ExCommand(0, 17, 36, 0, 0, 0, 1, 0, 0, 0); ex->_keyCode = 32; ex->_excFlags |= 3; ex->handle(); break; case Common::KEYCODE_s: if (_gamePaused) { _gamePaused = 0; _flgGameIsRunning = true; return; } ex = new ExCommand(0, 17, 36, 0, 0, 0, 1, 0, 0, 0); ex->_keyCode = event.kbd.keycode; ex->_excFlags |= 3; ex->handle(); break; case Common::KEYCODE_q: return; break; default: ex = new ExCommand(0, 17, 36, 0, 0, 0, 1, 0, 0, 0); ex->_keyCode = event.kbd.keycode; ex->_excFlags |= 3; ex->handle(); break; } break; case Common::EVENT_KEYUP: if (!_inputArFlag) { ex = new ExCommand(0, 17, 37, 0, 0, 0, 1, 0, 0, 0); ex->_excFlags |= 3; ex->handle(); } _keyState = Common::KEYCODE_INVALID; break; case Common::EVENT_MOUSEMOVE: if (_recordEvents) { ex = new ExCommand(0, 17, 31, event.mouse.x, event.mouse.y, 0, 1, 0, 0, 0); ex->_excFlags |= 3; ex->handle(); } _mouseScreenPos = event.mouse; break; case Common::EVENT_QUIT: _gameContinue = false; break; case Common::EVENT_RBUTTONDOWN: if (!_inputArFlag && (_updateTicks - _lastInputTicks) >= 2) { ex = new ExCommand(0, 17, 107, event.mouse.x, event.mouse.y, 0, 1, 0, 0, 0); ex->_excFlags |= 3; _lastInputTicks = _updateTicks; ex->handle(); } break; case Common::EVENT_LBUTTONDOWN: if (!_inputArFlag && (_updateTicks - _lastInputTicks) >= 2) { ex = new ExCommand(0, 17, 29, event.mouse.x, event.mouse.y, 0, 1, 0, 0, 0); ex->_sceneClickX = _sceneRect.left + ex->_x; ex->_sceneClickY = _sceneRect.top + ex->_y; ex->_keyCode = getGameLoaderInventory()->getSelectedItemId(); ex->_excFlags |= 3; _lastInputTicks = _updateTicks; ex->handle(); } break; case Common::EVENT_LBUTTONUP: if (!_inputArFlag && (_updateTicks - _lastButtonUpTicks) >= 2) { ex = new ExCommand(0, 17, 30, 0, 0, 0, 1, 0, 0, 0); ex->_excFlags |= 3; _lastButtonUpTicks = _updateTicks; ex->handle(); } break; default: break; } } #if 0 warning("STUB: FullpipeEngine::updateEvents() <mainWindowProc>"); if (Msg == MSG_SC11_SHOWSWING && _modalObject) { _modalObject->method14(); } #endif }
void GuiManager::runLoop() { Dialog * const activeDialog = getTopDialog(); bool didSaveState = false; if (activeDialog == 0) return; #ifdef ENABLE_EVENTRECORDER // Suspend recording while GUI is shown g_eventRec.suspendRecording(); #endif if (!_stateIsSaved) { saveState(); _theme->enable(); didSaveState = true; _useStdCursor = !_theme->ownCursor(); if (_useStdCursor) setupCursor(); // _theme->refresh(); _redrawStatus = kRedrawFull; redraw(); } Common::EventManager *eventMan = _system->getEventManager(); uint32 lastRedraw = 0; const uint32 waitTime = 1000 / 60; while (!_dialogStack.empty() && activeDialog == getTopDialog() && !eventMan->shouldQuit()) { redraw(); // Don't "tickle" the dialog until the theme has had a chance // to re-allocate buffers in case of a scaler change. activeDialog->handleTickle(); if (_useStdCursor) animateCursor(); // _theme->updateScreen(); // _system->updateScreen(); if (lastRedraw + waitTime < _system->getMillis(true)) { lastRedraw = _system->getMillis(true); _theme->updateScreen(); _system->updateScreen(); } Common::Event event; while (eventMan->pollEvent(event)) { // We will need to check whether the screen changed while polling // for an event here. While we do send EVENT_SCREEN_CHANGED // whenever this happens we still cannot be sure that we get such // an event immediately. For example, we might have an mouse move // event queued before an screen changed event. In some rare cases // this would make the GUI redraw (with the code a few lines // below) when it is not yet updated for new overlay dimensions. // As a result ScummVM would crash because it tries to copy data // outside the actual overlay screen. if (event.type != Common::EVENT_SCREEN_CHANGED) { checkScreenChange(); } // The top dialog can change during the event loop. In that case, flush all the // dialog-related events since they were probably generated while the old dialog // was still visible, and therefore not intended for the new one. // // This hopefully fixes strange behavior/crashes with pop-up widgets. (Most easily // triggered in 3x mode or when running ScummVM under Valgrind.) if (activeDialog != getTopDialog() && event.type != Common::EVENT_SCREEN_CHANGED) { processEvent(event, getTopDialog()); continue; } processEvent(event, activeDialog); if (lastRedraw + waitTime < _system->getMillis(true)) { lastRedraw = _system->getMillis(true); _theme->updateScreen(); _system->updateScreen(); } } if (_lastMousePosition.time + kTooltipDelay < _system->getMillis(true)) { Widget *wdg = activeDialog->findWidget(_lastMousePosition.x, _lastMousePosition.y); if (wdg && wdg->hasTooltip() && !(wdg->getFlags() & WIDGET_PRESSED)) { Tooltip *tooltip = new Tooltip(); tooltip->setup(activeDialog, wdg, _lastMousePosition.x, _lastMousePosition.y); tooltip->runModal(); delete tooltip; } } // Delay for a moment _system->delayMillis(10); } // WORKAROUND: When quitting we might not properly close the dialogs on // the dialog stack, thus we do this here to avoid any problems. // This is most noticable in bug #3481395 "LAUNCHER: Can't quit from unsupported game dialog". // It seems that Dialog::runModal never removes the dialog from the dialog // stack, thus if the dialog does not call Dialog::close to close itself // it will never be removed. Since we can have multiple run loops being // called we cannot rely on catching EVENT_QUIT in the event loop above, // since it would only catch it for the top run loop. if (eventMan->shouldQuit() && activeDialog == getTopDialog()) getTopDialog()->close(); if (didSaveState) { _theme->disable(); restoreState(); _useStdCursor = false; } #ifdef ENABLE_EVENTRECORDER // Resume recording once GUI is shown g_eventRec.resumeRecording(); #endif }