Ejemplo n.º 1
0
        public void Run()
        {
            SSEMath.Load();
            if (SDL.SDL_Init(SDL.SDL_INIT_VIDEO) != 0)
            {
                FLLog.Error("SDL", "SDL_Init failed, exiting.");
                return;
            }
            SDL.SDL_SetHint(SDL.SDL_HINT_IME_INTERNAL_EDITING, "1");
            SDL.SDL_SetHint(SDL.SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
            //Set GL states
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, 3);
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MINOR_VERSION, 2);
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_PROFILE_MASK, (int)SDL.SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_CORE);
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DEPTH_SIZE, 24);
            //Create Window
            var flags = SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE;

            if (fullscreen)
            {
                flags |= SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP;
            }
            var sdlWin = SDL.SDL_CreateWindow(
                "LibreLancer",
                SDL.SDL_WINDOWPOS_CENTERED,
                SDL.SDL_WINDOWPOS_CENTERED,
                width,
                height,
                flags
                );

            //Cursors
            curArrow      = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_ARROW);
            curMove       = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_CROSSHAIR);
            curTextInput  = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_IBEAM);
            curResizeNS   = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENS);
            curResizeEW   = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZEWE);
            curResizeNESW = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENESW);
            curResizeNWSE = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENWSE);
            //Window sizing
            if (minWindowSize != Point.Zero)
            {
                SDL.SDL_SetWindowMinimumSize(sdlWin, minWindowSize.X, minWindowSize.Y);
            }
            if (sdlWin == IntPtr.Zero)
            {
                FLLog.Error("SDL", "Failed to create window, exiting.");
                return;
            }
            windowptr = sdlWin;
            if (forceANGLE)
            {
                LoadANGLE();
            }
            else
            {
                var  glcontext = SDL.SDL_GL_CreateContext(sdlWin);
                bool check     = GL.CheckStringSDL();
                if (!check)
                {
                    FLLog.Warning("GL", "GL Version Insufficient - Using DX9");
                    SDL.SDL_GL_DeleteContext(glcontext);
                }
                if (glcontext == IntPtr.Zero || !check)
                {
                    if (Platform.RunningOS == OS.Windows)
                    {
                        LoadANGLE();
                    }
                    else
                    {
                        FLLog.Error("OpenGL", "Failed to create OpenGL context, exiting.");
                        return;
                    }
                }
                else
                {
                    GL.LoadSDL();
                    Renderer = string.Format("{0} ({1})", GL.GetString(GL.GL_VERSION), GL.GetString(GL.GL_RENDERER));
                }
            }
            SetVSync(true);
            //Init game state
            RenderState = new RenderState();
            Load();
            //Start game
            running = true;
            var timer = new Stopwatch();

            timer.Start();
            double last    = 0;
            double elapsed = 0;

            SDL.SDL_Event e;
            SDL.SDL_StopTextInput();
            while (running)
            {
                //Pump message queue
                while (SDL.SDL_PollEvent(out e) != 0)
                {
                    switch (e.type)
                    {
                    case SDL.SDL_EventType.SDL_QUIT:
                    {
                        if (WillClose != null)
                        {
                            WillClose();
                        }
                        running = false;                                 //TODO: Raise Event
                        break;
                    }

                    case SDL.SDL_EventType.SDL_MOUSEMOTION:
                    {
                        Mouse.X = e.motion.x;
                        Mouse.Y = e.motion.y;
                        Mouse.OnMouseMove();
                        break;
                    }

                    case SDL.SDL_EventType.SDL_MOUSEBUTTONDOWN:
                    {
                        Mouse.X = e.button.x;
                        Mouse.Y = e.button.y;
                        var btn = GetMouseButton(e.button.button);
                        Mouse.Buttons |= btn;
                        Mouse.OnMouseDown(btn);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_MOUSEBUTTONUP:
                    {
                        Mouse.X = e.button.x;
                        Mouse.Y = e.button.y;
                        var btn = GetMouseButton(e.button.button);
                        Mouse.Buttons &= ~btn;
                        Mouse.OnMouseUp(btn);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_MOUSEWHEEL:
                    {
                        Mouse.OnMouseWheel(e.wheel.y);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_TEXTINPUT:
                    {
                        Keyboard.OnTextInput(GetEventText(ref e));
                        break;
                    }

                    case SDL.SDL_EventType.SDL_KEYDOWN:
                    {
                        Keyboard.OnKeyDown((Keys)e.key.keysym.sym, (KeyModifiers)e.key.keysym.mod, e.key.repeat != 0);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_KEYUP:
                    {
                        Keyboard.OnKeyUp((Keys)e.key.keysym.sym, (KeyModifiers)e.key.keysym.mod);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_WINDOWEVENT:
                        if (e.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED)
                        {
                            SDL.SDL_GetWindowSize(windowptr, out width, out height);
                        }
                        break;
                    }
                }

                //Do game things
                if (!running)
                {
                    break;
                }
                Action work;
                while (actions.TryDequeue(out work))
                {
                    work();
                }
                totalTime = timer.Elapsed.TotalSeconds;
                Update(elapsed);
                if (!running)
                {
                    break;
                }
                Draw(elapsed);
                //Frame time before, FPS after
                var tk = timer.Elapsed.TotalSeconds - totalTime;
                frameTime = CalcAverageTime(tk);
                if (_screenshot)
                {
                    TakeScreenshot();
                    _screenshot = false;
                }
                if (angle != null)
                {
                    angle.SwapBuffers();
                }
                else
                {
                    SDL.SDL_GL_SwapWindow(sdlWin);
                }
                if (GL.FrameHadErrors())                  //If there was a GL error, track it down.
                {
                    GL.ErrorChecking = true;
                }
                elapsed         = timer.Elapsed.TotalSeconds - last;
                renderFrequency = (1.0 / CalcAverageTick(elapsed));
                last            = timer.Elapsed.TotalSeconds;
                totalTime       = timer.Elapsed.TotalSeconds;
                if (elapsed < 0)
                {
                    elapsed = 0;
                    FLLog.Warning("Timing", "Stopwatch returned negative time!");
                }
            }
            Cleanup();
            SDL.SDL_Quit();
        }
Ejemplo n.º 2
0
        public void Run()
        {
            FLLog.Info("Engine", "Version: " + Platform.GetInformationalVersion <Game>());
            //TODO: This makes i5-7200U on mesa 18 faster, but this should probably be a configurable option
            Environment.SetEnvironmentVariable("mesa_glthread", "true");
            SSEMath.Load();
            if (SDL.SDL_Init(SDL.SDL_INIT_VIDEO) != 0)
            {
                FLLog.Error("SDL", "SDL_Init failed, exiting.");
                return;
            }
            SDL.SDL_SetHint(SDL.SDL_HINT_IME_INTERNAL_EDITING, "1");
            SDL.SDL_SetHint(SDL.SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
            //Set GL states
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, 3);
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MINOR_VERSION, 2);
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_PROFILE_MASK, (int)SDL.SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_CORE);
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DEPTH_SIZE, 24);
            //Create Window
            var flags = SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE;

            if (fullscreen)
            {
                flags |= SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP;
            }
            var sdlWin = SDL.SDL_CreateWindow(
                "LibreLancer",
                SDL.SDL_WINDOWPOS_CENTERED,
                SDL.SDL_WINDOWPOS_CENTERED,
                width,
                height,
                flags
                );

            //Cursors
            curArrow      = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_ARROW);
            curMove       = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_CROSSHAIR);
            curTextInput  = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_IBEAM);
            curResizeNS   = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENS);
            curResizeEW   = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZEWE);
            curResizeNESW = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENESW);
            curResizeNWSE = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENWSE);
            //Window sizing
            if (minWindowSize != Point.Zero)
            {
                SDL.SDL_SetWindowMinimumSize(sdlWin, minWindowSize.X, minWindowSize.Y);
            }
            if (sdlWin == IntPtr.Zero)
            {
                FLLog.Error("SDL", "Failed to create window, exiting.");
                return;
            }
            SDL.SDL_EventState(SDL.SDL_EventType.SDL_DROPFILE, SDL.SDL_ENABLE);
            windowptr = sdlWin;
            var glcontext = SDL.SDL_GL_CreateContext(sdlWin);

            if (glcontext == IntPtr.Zero || !GL.CheckStringSDL())
            {
                SDL.SDL_GL_DeleteContext(glcontext);
                if (Platform.RunningOS == OS.Windows)
                {
                    SDL.SDL_ShowSimpleMessageBox(SDL.SDL_MessageBoxFlags.SDL_MESSAGEBOX_ERROR, "Librelancer", "Failed to create OpenGL context, exiting.", IntPtr.Zero);
                }
                FLLog.Error("OpenGL", "Failed to create OpenGL context, exiting.");
                return;
            }
            else
            {
                GL.LoadSDL();
                Renderer = string.Format("{0} ({1})", GL.GetString(GL.GL_VERSION), GL.GetString(GL.GL_RENDERER));
            }
            SetVSync(true);
            //Init game state
            RenderState = new RenderState();
            Load();
            //Start game
            running = true;
            timer   = new Stopwatch();
            timer.Start();
            double last    = 0;
            double elapsed = 0;

            SDL.SDL_Event e = new SDL.SDL_Event();
            SDL.SDL_StopTextInput();
            MouseButtons doRelease = 0;

            while (running)
            {
                //Window State
                var winFlags = (SDL.SDL_WindowFlags)SDL.SDL_GetWindowFlags(sdlWin);
                Focused = (winFlags & SDL.SDL_WindowFlags.SDL_WINDOW_MOUSE_FOCUS) ==
                          SDL.SDL_WindowFlags.SDL_WINDOW_MOUSE_FOCUS ||
                          (winFlags & SDL.SDL_WindowFlags.SDL_WINDOW_INPUT_FOCUS) ==
                          SDL.SDL_WindowFlags.SDL_WINDOW_INPUT_FOCUS;
                EventsThisFrame = false;
                //This allows for press/release in same frame to have
                //button down for one frame, e.g. trackpoint middle click on Linux/libinput.
                MouseButtons pressedThisFrame = 0;
                Mouse.Buttons &= ~doRelease;
                doRelease      = 0;
                bool eventWaited = false;
                if (waitForEvent)
                {
                    waitForEvent = false;
                    if (SDL.SDL_WaitEventTimeout(out e, 2000) != 0)
                    {
                        eventWaited = true;
                    }
                }
                //Pump message queue
                while (eventWaited || SDL.SDL_PollEvent(out e) != 0)
                {
                    eventWaited     = false;
                    EventsThisFrame = true;
                    switch (e.type)
                    {
                    case SDL.SDL_EventType.SDL_QUIT:
                    {
                        if (WillClose != null)
                        {
                            WillClose();
                        }
                        running = false;         //TODO: Raise Event
                        break;
                    }

                    case SDL.SDL_EventType.SDL_MOUSEMOTION:
                    {
                        Mouse.X = e.motion.x;
                        Mouse.Y = e.motion.y;
                        Mouse.OnMouseMove();
                        break;
                    }

                    case SDL.SDL_EventType.SDL_MOUSEBUTTONDOWN:
                    {
                        Mouse.X = e.button.x;
                        Mouse.Y = e.button.y;
                        var btn = GetMouseButton(e.button.button);
                        Mouse.Buttons    |= btn;
                        pressedThisFrame |= btn;
                        Mouse.OnMouseDown(btn);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_MOUSEBUTTONUP:
                    {
                        Mouse.X = e.button.x;
                        Mouse.Y = e.button.y;
                        var btn = GetMouseButton(e.button.button);
                        if ((pressedThisFrame & btn) == btn)
                        {
                            doRelease |= btn;
                        }
                        else
                        {
                            Mouse.Buttons &= ~btn;
                        }
                        Mouse.OnMouseUp(btn);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_MOUSEWHEEL:
                    {
                        Mouse.OnMouseWheel(e.wheel.y);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_TEXTINPUT:
                    {
                        Keyboard.OnTextInput(GetEventText(ref e));
                        break;
                    }

                    case SDL.SDL_EventType.SDL_KEYDOWN:
                    {
                        Keyboard.OnKeyDown((Keys)e.key.keysym.scancode, (KeyModifiers)e.key.keysym.mod, e.key.repeat != 0);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_KEYUP:
                    {
                        Keyboard.OnKeyUp((Keys)e.key.keysym.scancode, (KeyModifiers)e.key.keysym.mod);
                        break;
                    }

                    case SDL.SDL_EventType.SDL_KEYMAPCHANGED:
                        KeysExtensions.ResetKeyNames();
                        break;

                    case SDL.SDL_EventType.SDL_WINDOWEVENT:
                        if (e.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED)
                        {
                            SDL.SDL_GetWindowSize(windowptr, out width, out height);
                            OnResize();
                        }
                        break;

                    case SDL.SDL_EventType.SDL_DROPFILE:
                    {
                        var file = UnsafeHelpers.PtrToStringUTF8(e.drop.file);
                        OnDrop(file);
                        SDL.SDL_free(e.drop.file);
                        break;
                    }
                    }
                }

                //Do game things
                if (!running)
                {
                    break;
                }
                Action work;
                while (actions.TryDequeue(out work))
                {
                    work();
                }
                totalTime = timer.Elapsed.TotalSeconds;
                Update(elapsed);
                if (!running)
                {
                    break;
                }
                Draw(elapsed);
                //Frame time before, FPS after
                var tk = timer.Elapsed.TotalSeconds - totalTime;
                frameTime = CalcAverageTime(tk);
                if (_screenshot)
                {
                    TakeScreenshot();
                    _screenshot = false;
                }
                SDL.SDL_GL_SwapWindow(sdlWin);
                if (GL.FrameHadErrors()) //If there was a GL error, track it down.
                {
                    GL.ErrorChecking = true;
                }
                elapsed         = timer.Elapsed.TotalSeconds - last;
                renderFrequency = (1.0 / CalcAverageTick(elapsed));
                last            = timer.Elapsed.TotalSeconds;
                totalTime       = timer.Elapsed.TotalSeconds;
                if (elapsed < 0)
                {
                    elapsed = 0;
                    FLLog.Warning("Timing", "Stopwatch returned negative time!");
                }
            }
            Cleanup();
            SDL.SDL_Quit();
        }