/** * ProcessButEvent */ void ProcessButEvent(PLR_EVENT be) { if (_vm->_config->_swapButtons) { switch (be) { case PLR_SLEFT: be = PLR_SRIGHT; break; case PLR_DLEFT: be = PLR_DRIGHT; break; case PLR_SRIGHT: be = PLR_SLEFT; break; case PLR_DRIGHT: be = PLR_DLEFT; break; case PLR_DRAG1_START: be = PLR_DRAG2_START; break; case PLR_DRAG1_END: be = PLR_DRAG2_END; break; case PLR_DRAG2_START: be = PLR_DRAG1_START; break; case PLR_DRAG2_END: be = PLR_DRAG1_END; break; default: break; } } PlayerEvent(be, _vm->getMousePosition()); }
//------------------------------------------------------------------------------ void Dispatcher::play_P(PGM_P soundName, PGM_P motionName) { char buffer[PATH_BUFFER_SIZE]; Event motionOut; memset(buffer, 0x00, PATH_BUFFER_SIZE); strncpy_P(buffer, motionName, PATH_BUFFER_SIZE - 1); motion.dispatch(MotionEvent(PLAY, buffer), motionOut); Event playerOut; memset(buffer, 0x00, PATH_BUFFER_SIZE); strncpy_P(buffer, soundName, PATH_BUFFER_SIZE - 1); player.dispatch(PlayerEvent(PLAY, buffer), playerOut); bool motionFinished = false; bool soundFinished = false; do { if (motionOut.signal == END_OF_FILE) motionFinished = true; motion.dispatch(Event(TICK), motionOut); if (playerOut.signal == END_OF_FILE) soundFinished = true; player.dispatch(Event(TICK), playerOut); } while (!(motionFinished && soundFinished)); }
void ProcessKeyEvent(PLR_EVENT ke) { // Pass the keyboard event to the player event handler int xp, yp; GetCursorXYNoWait(&xp, &yp, true); const Common::Point mousePos(xp, yp); PlayerEvent(ke, mousePos); }
//------------------------------------------------------------------------------ void Dispatcher::play(const char* soundName, const char* motionName) { Event motionOut; motion.dispatch(MotionEvent(PLAY, motionName), motionOut); Event playerOut; player.dispatch(PlayerEvent(PLAY, soundName), playerOut); bool motionFinished = false; bool soundFinished = false; do { if (motionOut.signal == END_OF_FILE) motionFinished = true; motion.dispatch(Event(TICK), motionOut); if (playerOut.signal == END_OF_FILE) soundFinished = true; player.dispatch(Event(TICK), playerOut); } while (!(motionFinished && soundFinished)); }
/** * Handles launching a single click action result if the timeout for a double-click * expires */ static void SingleLeftProcess(CORO_PARAM, const void *) { CORO_BEGIN_CONTEXT; uint32 endTicks; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); // Work out when to wait until _ctx->endTicks = DwGetCurrentTime() + (uint32)dclickSpeed; // Timeout a double click (may not work once every 49 days!) do { CORO_SLEEP(1); } while (DwGetCurrentTime() < _ctx->endTicks); if (GetProvNotProcessed()) PlayerEvent(PLR_WALKTO, clickPos); CORO_KILL_SELF(); CORO_END_CODE; }
void ZoomOut(const CTimeValue& t, const Vec3& pos) { PlayerEvent(t, "zoom_out", 0, 0, pos ); }
void ZoomIn(const CTimeValue& t, const Vec3& pos) { PlayerEvent(t, "zoom_in", 0, 0, pos ); }
void FiremodeChanged(const CTimeValue& t, const Vec3& pos, const char* modeName) { PlayerEvent(t, "firemode_changed", modeName, 0, pos ); }
void Reload(const CTimeValue& t, const Vec3& pos) { m_weapons.Reload(); PlayerEvent(t, "reload", m_weapons.GetCurrent(), 0, pos); }
void WeaponShot(int pel, const CTimeValue& t, const Vec3& pos) { m_weapons.Shot(pel); PlayerEvent(t, "fire", m_weapons.GetCurrent(), pel, pos); }
void Spectator(bool spectator, const CTimeValue& time) { if(spectator) m_weapons.DeselectWeapon(time); PlayerEvent(time, "spectator", "", spectator?1:0, ZERO); }
/** * Process to handle changes in the mouse buttons. */ static void MouseProcess(CORO_PARAM, const void *) { // COROUTINE CORO_BEGIN_CONTEXT; bool lastLWasDouble; bool lastRWasDouble; uint32 lastLeftClick, lastRightClick; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); _ctx->lastLWasDouble = false; _ctx->lastRWasDouble = false; _ctx->lastLeftClick = _ctx->lastRightClick = DwGetCurrentTime(); while (true) { if (mouseButtons.empty()) { // allow scheduling CORO_SLEEP(1); continue; } // get next mouse button event Common::EventType type = *mouseButtons.begin(); mouseButtons.erase(mouseButtons.begin()); int xp, yp; GetCursorXYNoWait(&xp, &yp, true); const Common::Point mousePos(xp, yp); switch (type) { case Common::EVENT_LBUTTONDOWN: // left button press if (DwGetCurrentTime() - _ctx->lastLeftClick < (uint32)dclickSpeed) { // Left button double-click if (TinselV2) { // Kill off the button process and fire off the action command g_scheduler->killMatchingProcess(PID_BTN_CLICK, -1); PlayerEvent(PLR_ACTION, clickPos); } else { // signal left drag start ProcessButEvent(PLR_DRAG1_START); // signal left double click event ProcessButEvent(PLR_DLEFT); } _ctx->lastLWasDouble = true; } else { // Initial mouse down - either for a single click, or potentially // the start of a double-click action if (TinselV2) { PlayerEvent(PLR_DRAG1_START, mousePos); ProvNotProcessed(); PlayerEvent(PLR_PROV_WALKTO, mousePos); } else { // signal left drag start ProcessButEvent(PLR_DRAG1_START); // signal left single click event ProcessButEvent(PLR_SLEFT); } _ctx->lastLWasDouble = false; } break; case Common::EVENT_LBUTTONUP: // left button release // update click timer if (_ctx->lastLWasDouble == false) { _ctx->lastLeftClick = DwGetCurrentTime(); // If player control is enabled, start a process which, if it times out, // will activate a single button click if (TinselV2 && ControlIsOn()) { clickPos = mousePos; g_scheduler->createProcess(PID_BTN_CLICK, SingleLeftProcess, NULL, 0); } } else _ctx->lastLeftClick -= dclickSpeed; if (TinselV2) // Signal left drag end PlayerEvent(PLR_DRAG1_END, mousePos); else // signal left drag end ProcessButEvent(PLR_DRAG1_END); break; case Common::EVENT_RBUTTONDOWN: // right button press if (DwGetCurrentTime() - _ctx->lastRightClick < (uint32)dclickSpeed) { // Right button double-click if (TinselV2) { PlayerEvent(PLR_NOEVENT, clickPos); } else { // signal right drag start ProcessButEvent(PLR_DRAG2_START); // signal right double click event ProcessButEvent(PLR_DRIGHT); } _ctx->lastRWasDouble = true; } else { if (TinselV2) { PlayerEvent(PLR_DRAG2_START, mousePos); PlayerEvent(PLR_LOOK, mousePos); } else { // signal right drag start ProcessButEvent(PLR_DRAG2_START); // signal right single click event ProcessButEvent(PLR_SRIGHT); } _ctx->lastRWasDouble = false; } break; case Common::EVENT_RBUTTONUP: // right button release // update click timer if (_ctx->lastRWasDouble == false) _ctx->lastRightClick = DwGetCurrentTime(); else _ctx->lastRightClick -= dclickSpeed; if (TinselV2) // Signal left drag end PlayerEvent(PLR_DRAG2_END, mousePos); else // signal right drag end ProcessButEvent(PLR_DRAG2_END); break; default: break; } } CORO_END_CODE; }
//------------------------------------------------------------------------------ void Dispatcher::loop() { Event buttonOut; switch (digitalRead(PIN_BUTTON)) { case LOW : button.dispatch(Event(CONTACT_DETECTED), buttonOut); break; case HIGH : button.dispatch(Event(NO_CONTACT_DETECTED), buttonOut); break; } Event persoOut; switch (buttonOut.signal) { case SHORT_CLICK_RELEASED : personality.dispatch(Event(SHORT_CLICK_RELEASED), persoOut); break; case SUPERLONG_CLICK_ARMED : personality.dispatch(Event(SUPERLONG_CLICK_ARMED), persoOut); break; case NOTHING : personality.dispatch(Event(TICK), persoOut); break; } Event playerOut, motionOut; char* soundName; char* motionName; switch (persoOut.signal) { case WAKE_UP : { facebook.updateContent(); twitter.updateContent(); email.updateContent(); if (settings.fetch() >= 0) { settings.save(); } resources.synchronize(); char soundName[PATH_BUFFER_SIZE] = {0}; strncpy_P(soundName, SOUND_WAKE, PATH_BUFFER_SIZE - 1); player.dispatch(PlayerEvent(PLAY, soundName), playerOut); break; } case FALL_ASLEEP : { char soundName[PATH_BUFFER_SIZE] = {0}; strncpy_P(soundName, SOUND_SLEEP, PATH_BUFFER_SIZE - 1); player.dispatch(PlayerEvent(PLAY, soundName), playerOut); break; } case GMAIL: if (gmail.enabled() && gmail.update()) { soundName = gmail.getSoundFilename(); motionName = gmail.getMotionFilename(); play(soundName, motionName); } personality.dispatch(Event(STOP), persoOut); break; case FACEBOOK : if (facebook.Service::enabled() && facebook.update()) { soundName = facebook.getSoundFilename(); motionName = facebook.getMotionFilename(); play(soundName, motionName); } personality.dispatch(Event(STOP), persoOut); break; case TWITTER : if (twitter.Service::enabled() && twitter.update()) { soundName = twitter.getSoundFilename(); motionName = twitter.getMotionFilename(); play(soundName, motionName); } personality.dispatch(Event(STOP), persoOut); break; case RSS : if (rss.enabled() && rss.update()) { soundName = rss.getSoundFilename(); motionName = rss.getMotionFilename(); play(soundName, motionName); } personality.dispatch(Event(STOP), persoOut); break; case FOURSQUARE : if (foursquare.Service::enabled() && foursquare.update()) { soundName = foursquare.getSoundFilename(); motionName = foursquare.getMotionFilename(); play(soundName, motionName); } personality.dispatch(Event(STOP), persoOut); break; case SOUNDCLOUD : if (soundcloud.downloadsEnabled() && soundcloud.download()) { personality.dispatch(Event(SOUNDCLOUD), persoOut); player.dispatch(PlayerEvent(PLAY, soundcloud.filepath()), playerOut); } else { playerOut.signal = END_OF_FILE; motionOut.signal = END_OF_FILE; } if (!api.connected()) { api.connect(); } break; case ACTION : if (twitter.Action::enabled()) { if (twitter.trigger()) { audio.play_P(SOUND_AOK); } else { audio.play_P(SOUND_ERR); } } if (facebook.Action::enabled()) { if (facebook.trigger()) { audio.play_P(SOUND_AOK); } else { audio.play_P(SOUND_ERR); } } if (foursquare.Action::enabled()) { if (foursquare.trigger()) { audio.play_P(SOUND_AOK); } else { audio.play_P(SOUND_ERR); } } if (email.Action::enabled()) { if (email.trigger()) { audio.play_P(SOUND_AOK); } else { audio.play_P(SOUND_ERR); } } if (soundcloud.Action::enabled()) { char directory[PATH_BUFFER_SIZE] = {0}; strncpy_P(directory, soundcloud.directory(), PATH_BUFFER_SIZE - 1); player.dispatch(PlayerEvent(RANDOM, directory), playerOut); personality.dispatch(Event(SOUNDCLOUD), persoOut); } else { personality.dispatch(Event(STOP), persoOut); } break; case NOTHING : player.dispatch(Event(TICK), playerOut); motion.dispatch(Event(TICK), motionOut); break; } if (playerOut.signal == END_OF_FILE) { motion.dispatch(Event(STOP)); player.dispatch(Event(STOP)); personality.dispatch(Event(STOP), persoOut); } }