static void handleSensorEvent(bps_event_t *event) { if (SENSOR_AZIMUTH_PITCH_ROLL_READING == bps_event_get_code(event)) { float azimuth, pitch, roll; float result_x = 0.0f, result_y = -1.0f; sensor_event_get_apr(event, &azimuth, &pitch, &roll); float radians = abs(roll) * M_PI / 180 ;//+ adjustment_angle; float horizontal = sin(radians) * 0.5f; float vertical = cos(radians) * 0.5f; if (pitch < 0) { vertical = -vertical; } if (roll >= 0) { horizontal = -horizontal; } //Account for axis change due to different starting orientations if (orientation_angle == 0) { result_x = horizontal; result_y = vertical; } else if (orientation_angle == 90) { result_x = -vertical; result_y = horizontal; } else if (orientation_angle == 180) { result_x = -horizontal; result_y = -vertical; } else if (orientation_angle == 270) { result_x = vertical; result_y = -horizontal; } set_gravity(result_x, result_y); } }
int Platform::enterMessagePump() { GP_ASSERT(_game); int rc; int eventType; int flags; int value; int position[2]; int domain; mtouch_event_t touchEvent; bool suspended = false; // Get the initial time. clock_gettime(CLOCK_REALTIME, &__timespec); __timeStart = timespec2millis(&__timespec); __timeAbsolute = 0L; _game->run(); // Message loop. while (true) { bps_event_t* event = NULL; while (true) { rc = bps_get_event(&event, 1); GP_ASSERT(rc == BPS_SUCCESS); if (event == NULL) break; domain = bps_event_get_domain(event); if (domain == screen_get_domain()) { __screenEvent = screen_event_get_event(event); screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_TYPE, &eventType); switch (eventType) { case SCREEN_EVENT_MTOUCH_TOUCH: { screen_get_mtouch_event(__screenEvent, &touchEvent, 0); if (__gestureEventsProcessed.any()) rc = gestures_set_process_event(__gestureSet, &touchEvent, NULL); if ( !rc && (__multiTouch || touchEvent.contact_id == 0) ) { gameplay::Platform::touchEventInternal(Touch::TOUCH_PRESS, touchEvent.x, touchEvent.y, touchEvent.contact_id); } break; } case SCREEN_EVENT_MTOUCH_RELEASE: { screen_get_mtouch_event(__screenEvent, &touchEvent, 0); if (__gestureEventsProcessed.any()) rc = gestures_set_process_event(__gestureSet, &touchEvent, NULL); if ( !rc && (__multiTouch || touchEvent.contact_id == 0) ) { gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, touchEvent.x, touchEvent.y, touchEvent.contact_id); } if (__gestureSwipeRecognized) { __gestureSwipeRecognized = false; } break; } case SCREEN_EVENT_MTOUCH_MOVE: { screen_get_mtouch_event(__screenEvent, &touchEvent, 0); if (__gestureEventsProcessed.any()) rc = gestures_set_process_event(__gestureSet, &touchEvent, NULL); if ( !rc && (__multiTouch || touchEvent.contact_id == 0) ) { gameplay::Platform::touchEventInternal(Touch::TOUCH_MOVE, touchEvent.x, touchEvent.y, touchEvent.contact_id); } break; } case SCREEN_EVENT_POINTER: { static int mouse_pressed = 0; int buttons; int wheel; // A move event will be fired unless a button state changed. bool move = true; bool left_move = false; // This is a mouse move event, it is applicable to a device with a usb mouse or simulator. screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_BUTTONS, &buttons); screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_SOURCE_POSITION, position); screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_MOUSE_WHEEL, &wheel); // Handle left mouse. Interpret as touch if the left mouse event is not consumed. if (buttons & SCREEN_LEFT_MOUSE_BUTTON) { if (mouse_pressed & SCREEN_LEFT_MOUSE_BUTTON) { left_move = true; } else { move = false; mouse_pressed |= SCREEN_LEFT_MOUSE_BUTTON; mouseOrTouchEvent(Mouse::MOUSE_PRESS_LEFT_BUTTON, Touch::TOUCH_PRESS, position[0], position[1]); } } else if (mouse_pressed & SCREEN_LEFT_MOUSE_BUTTON) { move = false; mouse_pressed &= ~SCREEN_LEFT_MOUSE_BUTTON; mouseOrTouchEvent(Mouse::MOUSE_RELEASE_LEFT_BUTTON, Touch::TOUCH_RELEASE, position[0], position[1]); } // Handle right mouse. if (buttons & SCREEN_RIGHT_MOUSE_BUTTON) { if ((mouse_pressed & SCREEN_RIGHT_MOUSE_BUTTON) == 0) { move = false; mouse_pressed |= SCREEN_RIGHT_MOUSE_BUTTON; gameplay::Platform::mouseEventInternal(Mouse::MOUSE_PRESS_RIGHT_BUTTON, position[0], position[1], 0); } } else if (mouse_pressed & SCREEN_RIGHT_MOUSE_BUTTON) { move = false; mouse_pressed &= ~SCREEN_RIGHT_MOUSE_BUTTON; gameplay::Platform::mouseEventInternal(Mouse::MOUSE_RELEASE_RIGHT_BUTTON, position[0], position[1], 0); } // Handle middle mouse. if (buttons & SCREEN_MIDDLE_MOUSE_BUTTON) { if ((mouse_pressed & SCREEN_MIDDLE_MOUSE_BUTTON) == 0) { move = false; mouse_pressed |= SCREEN_MIDDLE_MOUSE_BUTTON; gameplay::Platform::mouseEventInternal(Mouse::MOUSE_PRESS_MIDDLE_BUTTON, position[0], position[1], 0); } } else if (mouse_pressed & SCREEN_MIDDLE_MOUSE_BUTTON) { move = false; mouse_pressed &= ~SCREEN_MIDDLE_MOUSE_BUTTON; gameplay::Platform::mouseEventInternal(Mouse::MOUSE_RELEASE_MIDDLE_BUTTON, position[0], position[1], 0); } // Fire a move event if none of the buttons changed. if (left_move) { mouseOrTouchEvent(Mouse::MOUSE_MOVE, Touch::TOUCH_MOVE, position[0], position[1]); } else if (move) { gameplay::Platform::mouseEventInternal(Mouse::MOUSE_MOVE, position[0], position[1], 0); } // Handle mouse wheel events. if (wheel) { gameplay::Platform::mouseEventInternal(Mouse::MOUSE_WHEEL, position[0], position[1], -wheel); } break; } case SCREEN_EVENT_KEYBOARD: { screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_KEY_FLAGS, &flags); screen_get_event_property_iv(__screenEvent, SCREEN_PROPERTY_KEY_SYM, &value); gameplay::Keyboard::KeyEvent evt = (flags & KEY_DOWN) ? gameplay::Keyboard::KEY_PRESS : gameplay::Keyboard::KEY_RELEASE; // Suppress key repeats. if ((flags & KEY_REPEAT) == 0) { keyEventInternal(evt, getKey(value)); if (evt == gameplay::Keyboard::KEY_PRESS && (flags & KEY_SYM_VALID)) { int unicode = getUnicode(value); if (unicode) keyEventInternal(gameplay::Keyboard::KEY_CHAR, unicode); } } break; } } } else if (domain == navigator_get_domain()) { switch (bps_event_get_code(event)) { case NAVIGATOR_SWIPE_DOWN: _game->menuEvent(); break; case NAVIGATOR_WINDOW_STATE: { navigator_window_state_t state = navigator_event_get_window_state(event); switch (state) { case NAVIGATOR_WINDOW_FULLSCREEN: _game->resume(); suspended = false; break; case NAVIGATOR_WINDOW_THUMBNAIL: case NAVIGATOR_WINDOW_INVISIBLE: if (!suspended) _game->pause(); suspended = true; break; } break; } case NAVIGATOR_EXIT: _game->exit(); break; } } else if (domain == sensor_get_domain()) { if (bps_event_get_code(event) == SENSOR_AZIMUTH_PITCH_ROLL_READING) { float azimuth; sensor_event_get_apr(event, &azimuth, &__pitch, &__roll); } } } // If we are done, then exit. if (_game->getState() == Game::UNINITIALIZED) break; if (!suspended) { _game->frame(); // Post the new frame to the display. // Note that there are a couple cases where eglSwapBuffers could fail // with an error code that requires a certain level of re-initialization: // // 1) EGL_BAD_NATIVE_WINDOW - Called when the surface we're currently using // is invalidated. This would require us to destroy our EGL surface, // close our OpenKODE window, and start again. // // 2) EGL_CONTEXT_LOST - Power management event that led to our EGL context // being lost. Requires us to re-create and re-initalize our EGL context // and all OpenGL ES state. // // For now, if we get these, we'll simply exit. rc = eglSwapBuffers(__eglDisplay, __eglSurface); if (rc != EGL_TRUE) { _game->exit(); perror("eglSwapBuffers"); break; } } } screen_stop_events(__screenContext); bps_shutdown(); screen_destroy_context(__screenContext); return 0; }