예제 #1
0
        internal bool InnerLoopTick()
        {
            SDL.SDL_Event evt;

#if !THREADED_GL
            Threading.Run();
#endif
            while (SDL.SDL_PollEvent(out evt) == 1)
            {
                // Keyboard
                if (evt.type == SDL.SDL_EventType.SDL_KEYDOWN)
                {
#if USE_SCANCODES
                    Keys key = SDL2_KeyboardUtil.ToXNA(evt.key.keysym.scancode);
#else
                    Keys key = SDL2_KeyboardUtil.ToXNA(evt.key.keysym.sym);
#endif
                    if (!keys.Contains(key))
                    {
                        keys.Add(key);
                        INTERNAL_TextInputIn(key);
                    }
                }
                else if (evt.type == SDL.SDL_EventType.SDL_KEYUP)
                {
#if USE_SCANCODES
                    Keys key = SDL2_KeyboardUtil.ToXNA(evt.key.keysym.scancode);
#else
                    Keys key = SDL2_KeyboardUtil.ToXNA(evt.key.keysym.sym);
#endif
                    if (keys.Remove(key))
                    {
                        INTERNAL_TextInputOut(key);
                    }
                }

                // Mouse Input
                else if (evt.type == SDL.SDL_EventType.SDL_MOUSEMOTION)
                {
                    Mouse.INTERNAL_IsWarped = false;
                }
                else if (evt.type == SDL.SDL_EventType.SDL_MOUSEWHEEL)
                {
                    // 120 units per notch. Because reasons.
                    Mouse.INTERNAL_MouseWheel += evt.wheel.y * 120;
                }

                // Touch Input
                else if (evt.type == SDL.SDL_EventType.SDL_FINGERDOWN)
                {
                    TouchPanel.AddEvent(
                        (int)evt.tfinger.touchId,
                        TouchLocationState.Pressed,
                        new Vector2(
                            evt.tfinger.x,
                            evt.tfinger.y
                            )
                        );
                }
                else if (evt.type == SDL.SDL_EventType.SDL_FINGERUP)
                {
                    TouchPanel.AddEvent(
                        (int)evt.tfinger.touchId,
                        TouchLocationState.Released,
                        new Vector2(
                            evt.tfinger.x,
                            evt.tfinger.y
                            )
                        );
                }
                else if (evt.type == SDL.SDL_EventType.SDL_FINGERMOTION)
                {
                    TouchPanel.AddEvent(
                        (int)evt.tfinger.touchId,
                        TouchLocationState.Moved,
                        new Vector2(
                            evt.tfinger.x,
                            evt.tfinger.y
                            )
                        );
                }

                // Various Window Events...
                else if (evt.type == SDL.SDL_EventType.SDL_WINDOWEVENT)
                {
                    // Window Focus
                    if (evt.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_FOCUS_GAINED)
                    {
                        IsActive = true;

                        if (!INTERNAL_useFullscreenSpaces)
                        {
                            // If we alt-tab away, we lose the 'fullscreen desktop' flag on some WMs
                            SDL.SDL_SetWindowFullscreen(
                                Window.Handle,
                                Game.GraphicsDevice.PresentationParameters.IsFullScreen ?
                                (uint)SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP :
                                0
                                );
                        }

                        // Disable the screensaver when we're back.
                        SDL.SDL_DisableScreenSaver();
                    }
                    else if (evt.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_FOCUS_LOST)
                    {
                        IsActive = false;

                        if (!INTERNAL_useFullscreenSpaces)
                        {
                            SDL.SDL_SetWindowFullscreen(Window.Handle, 0);
                        }

                        // Give the screensaver back, we're not that important now.
                        SDL.SDL_EnableScreenSaver();
                    }

                    // Window Resize
                    else if (evt.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED)
                    {
                        Mouse.INTERNAL_WindowWidth  = evt.window.data1;
                        Mouse.INTERNAL_WindowHeight = evt.window.data2;

                        // Should be called on user resize only, NOT ApplyChanges!
                        ((SDL2_GameWindow)Window).INTERNAL_ClientSizeChanged();
                    }
                    else if (evt.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_SIZE_CHANGED)
                    {
                        Mouse.INTERNAL_WindowWidth  = evt.window.data1;
                        Mouse.INTERNAL_WindowHeight = evt.window.data2;

                        // Need to reset the graphics device any time the window size changes
                        if (Game.graphicsDeviceManager.IsFullScreen)
                        {
                            GraphicsDevice device = Game.GraphicsDevice;
                            Game.graphicsDeviceManager.INTERNAL_ResizeGraphicsDevice(
                                device.GLDevice.Backbuffer.Width,
                                device.GLDevice.Backbuffer.Height
                                );
                        }
                        else
                        {
                            Game.graphicsDeviceManager.INTERNAL_ResizeGraphicsDevice(
                                evt.window.data1,
                                evt.window.data2
                                );
                        }
                    }

                    // Window Move
                    else if (evt.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_MOVED)
                    {
                        /* Apparently if you move the window to a new
                         * display, a GraphicsDevice Reset occurs.
                         * -flibit
                         */
                        int newIndex = SDL.SDL_GetWindowDisplayIndex(
                            Window.Handle
                            );
                        if (newIndex != displayIndex)
                        {
                            displayIndex = newIndex;
                            INTERNAL_GenerateDisplayModes();
                            Game.GraphicsDevice.Reset();
                        }
                    }

                    // Mouse Focus
                    else if (evt.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_ENTER)
                    {
                        SDL.SDL_DisableScreenSaver();
                    }
                    else if (evt.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_LEAVE)
                    {
                        SDL.SDL_EnableScreenSaver();
                    }
                }

                // Controller device management
                else if (evt.type == SDL.SDL_EventType.SDL_JOYDEVICEADDED)
                {
                    GamePad.INTERNAL_AddInstance(evt.jdevice.which);
                }
                else if (evt.type == SDL.SDL_EventType.SDL_JOYDEVICEREMOVED)
                {
                    GamePad.INTERNAL_RemoveInstance(evt.jdevice.which);
                }

                // Text Input
                else if (evt.type == SDL.SDL_EventType.SDL_TEXTINPUT && !INTERNAL_TextInputSuppress)
                {
                    string text;

                    // Based on the SDL2# LPUtf8StrMarshaler
                    unsafe {
                        byte *endPtr = evt.text.text;
                        while (*endPtr != 0)
                        {
                            endPtr++;
                        }
                        byte[] bytes = new byte[endPtr - evt.text.text];
                        Marshal.Copy((IntPtr)evt.text.text, bytes, 0, bytes.Length);
                        text = System.Text.Encoding.UTF8.GetString(bytes);
                    }

                    if (text.Length > 0)
                    {
                        TextInputEXT.OnTextInput(text[0]);
                    }
                }

                // Quit
                else if (evt.type == SDL.SDL_EventType.SDL_QUIT)
                {
                    INTERNAL_runApplication = false;
                    break;
                }
            }
            // Text Input Controls Key Handling
            INTERNAL_TextInputUpdate();

            Keyboard.SetKeys(keys);
            Game.Tick();

            return(INTERNAL_runApplication);
        }
예제 #2
0
        // Return true to trigger worker thread pause
        bool RunIteration(CancellationToken token)
        {
            // set main game thread global ID
            Threading.ResetThread(Thread.CurrentThread.ManagedThreadId);

            InternalState currentState = InternalState.Exited_GameThread;

            lock (_lockObject)
            {
                currentState = _internalState;
            }

            switch (currentState)
            {
            // exit states
            case InternalState.Exiting:     // when ui thread wants to exit
                processStateExiting();
                break;

            case InternalState.Exited_GameThread:     // when game thread processed exiting event
                lock (_lockObject)
                {
                    _waitForExitedStateProcessed.Set();
                    cts.Cancel();
                }
                break;

            // pause states
            case InternalState.Pausing_UIThread:     // when ui thread wants to pause
                processStatePausing();
                break;

            case InternalState.Paused_GameThread:     // when game thread processed pausing event

                // this must be processed outside of this loop, in the new task thread!
                return(true);    // trigger pause of worker thread

            // other states
            case InternalState.Resuming_UIThread:     // when ui thread wants to resume
                processStateResuming();

                // pause must wait for resume in case pause/resume is called in very quick succession
                lock (_lockObject)
                {
                    _waitForResumedStateProcessed.Set();
                }
                break;

            case InternalState.Running_GameThread:     // when we are running game
                processStateRunning(token);

                break;

            case InternalState.ForceRecreateSurface:
                processStateForceSurfaceRecreation();
                break;

            // default case, error
            default:
                processStateDefault();
                cts.Cancel();
                break;
            }

            return(false);
        }
예제 #3
0
        public void INTERNAL_RunLoop()
        {
            // Now that we're in the game loop, this should be safe.
            Game.GraphicsDevice.glFramebuffer = INTERNAL_glFramebuffer;

            SDL.SDL_Event evt;

            while (INTERNAL_runApplication)
            {
#if !THREADED_GL
                Threading.Run();
#endif
                while (SDL.SDL_PollEvent(out evt) == 1)
                {
                    // TODO: All events...

                    // Keyboard
                    if (evt.type == SDL.SDL_EventType.SDL_KEYDOWN)
                    {
                        Keys key = SDL2_KeyboardUtil.ToXNA(evt.key.keysym.scancode);
                        if (!keys.Contains(key))
                        {
                            keys.Add(key);
                            INTERNAL_TextInputIn(key);
                        }
                    }
                    else if (evt.type == SDL.SDL_EventType.SDL_KEYUP)
                    {
                        Keys key = SDL2_KeyboardUtil.ToXNA(evt.key.keysym.scancode);
                        if (keys.Contains(key))
                        {
                            keys.Remove(key);
                            INTERNAL_TextInputOut(key);
                        }
                    }

                    // Various Window Events...
                    else if (evt.type == SDL.SDL_EventType.SDL_WINDOWEVENT)
                    {
                        // Window Focus
                        if (evt.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_FOCUS_GAINED)
                        {
                            IsActive = true;

                            // If we alt-tab away, we lose the 'fullscreen desktop' flag on some WMs
                            SDL.SDL_SetWindowFullscreen(INTERNAL_sdlWindow, (uint)INTERNAL_sdlWindowFlags_Current);

                            // Disable the screensaver when we're back.
                            SDL.SDL_DisableScreenSaver();
                        }
                        else if (evt.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_FOCUS_LOST)
                        {
                            IsActive = false;

                            SDL.SDL_SetWindowFullscreen(INTERNAL_sdlWindow, 0);

                            // Give the screensaver back, we're not that important now.
                            SDL.SDL_EnableScreenSaver();
                        }

                        // Window Resize
                        else if (evt.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED)
                        {
                            Mouse.INTERNAL_WindowWidth  = evt.window.data1;
                            Mouse.INTERNAL_WindowHeight = evt.window.data2;

                            // Should be called on user resize only, NOT ApplyChanges!.
                            OnClientSizeChanged();
                        }
                        else if (evt.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_SIZE_CHANGED)
                        {
                            Mouse.INTERNAL_WindowWidth  = evt.window.data1;
                            Mouse.INTERNAL_WindowHeight = evt.window.data2;
                        }

                        // Mouse Focus
                        else if (evt.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_ENTER)
                        {
                            SDL.SDL_DisableScreenSaver();
                        }
                        else if (evt.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_LEAVE)
                        {
                            SDL.SDL_EnableScreenSaver();
                        }
                    }

                    // Mouse Wheel
                    else if (evt.type == SDL.SDL_EventType.SDL_MOUSEWHEEL)
                    {
                        Mouse.INTERNAL_MouseWheel += evt.wheel.y;
                    }

                    // Controller device management
                    else if (evt.type == SDL.SDL_EventType.SDL_JOYDEVICEADDED)
                    {
                        Input.GamePad.INTERNAL_AddInstance(evt.jdevice.which);
                    }
                    else if (evt.type == SDL.SDL_EventType.SDL_JOYDEVICEREMOVED)
                    {
                        Input.GamePad.INTERNAL_RemoveInstance(evt.jdevice.which);
                    }

                    // Text Input
                    else if (evt.type == SDL.SDL_EventType.SDL_TEXTINPUT && !INTERNAL_TextInputSuppress)
                    {
                        string text;
                        unsafe { text = new string((char *)evt.text.text); }
                        if (text.Length > 0)
                        {
                            OnTextInput(evt, new TextInputEventArgs(text[0]));
                        }
                    }

                    // Quit
                    else if (evt.type == SDL.SDL_EventType.SDL_QUIT)
                    {
                        INTERNAL_runApplication = false;
                        break;
                    }
                }
                // Text Input Controls Key Handling
                INTERNAL_TextInputUpdate();

                if (keys.Contains(Keys.LeftAlt) && keys.Contains(Keys.F4))
                {
                    INTERNAL_runApplication = false;
                }

                Keyboard.SetKeys(keys);
                Game.Tick();
            }

            // We out.
            Game.Exit();
        }