double Platform::getAbsoluteTime()
{
    clock_gettime(CLOCK_REALTIME, &__timespec);
    double now = timespec2millis(&__timespec);
    __timeAbsolute = now - __timeStart;

    return __timeAbsolute;
}
Exemplo n.º 2
0
    int Platform::enterMessagePump()
    {
        GP_ASSERT(_game);

        updateWindowSize();

        // Get the initial time.
        clock_gettime(CLOCK_REALTIME, &__timespec);
        __timeStart = timespec2millis(&__timespec);
        __timeAbsolute = 0L;

        if (_game->getState() != Game::RUNNING)
            _game->run();

        if (__attachToWindow)
            return 0;

        // Do something

        return 0;
    }
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;
}