예제 #1
0
 internal static void WarningWhenFails(this Log log, string msg, Func <int> func)
 {
     if (func() < 0)
     {
         log.Warning($"{msg}: {SDL2.SDL_GetError()}");
     }
 }
예제 #2
0
        internal void FixedUpdate()
        {
            var currentTime = SDL2.SDL_GetTicks();

            Lag += (currentTime - _lastLagMeasureTime) / 1000f;
            _lastLagMeasureTime = currentTime;
        }
예제 #3
0
        public override void Play()
        {
            EnsureHandleValid();

            if (Status == PlaybackStatus.Playing)
            {
                if (SDL2_nmix.NMIX_Pause(Handle) < 0)
                {
                    _log.Error($"Failed to play the audio source [pause]: {SDL2.SDL_GetError()}");
                    return;
                }

                if (SDL2_nmix.NMIX_Rewind(FileSourceHandle) < 0)
                {
                    _log.Error($"Failed to play the audio source [rewind]: {SDL2.SDL_GetError()}");
                    return;
                }

                Status = PlaybackStatus.Stopped;
            }

            if (SDL2_nmix.NMIX_Play(Handle) < 0)
            {
                _log.Error($"Failed to play the audio source [play]: {SDL2.SDL_GetError()}");
                return;
            }

            Status = PlaybackStatus.Playing;
        }
예제 #4
0
        private void ControllerConnected(Window owner, SDL2.SDL_Event ev)
        {
            var instance    = SDL2.SDL_GameControllerOpen(ev.cdevice.which);
            var joyInstance = SDL2.SDL_GameControllerGetJoystick(instance);
            var instanceId  = SDL2.SDL_JoystickInstanceID(joyInstance);

            var playerIndex = ControllerRegistry.Instance.GetFirstFreePlayerSlot();

            SDL2.SDL_GameControllerSetPlayerIndex(instance, playerIndex);

            var name        = SDL2.SDL_GameControllerName(instance);
            var productInfo = new ProductInfo(
                SDL2.SDL_GameControllerGetVendor(instance),
                SDL2.SDL_GameControllerGetProduct(instance)
                );

            var guid = SDL2.SDL_JoystickGetGUID(joyInstance);

            var controllerInfo = new ControllerInfo(instance, instanceId, guid, playerIndex, name, productInfo);

            ControllerRegistry.Instance.Register(instance, controllerInfo);

            owner.Game.OnControllerConnected(
                new ControllerEventArgs(controllerInfo)
                );
        }
예제 #5
0
        private static void InitializeSdlSystems()
        {
            Console.WriteLine("---");
            Console.WriteLine("Initializing SDL2 core...");

            SDL2.SDL_Init(BootConfig.SdlModules.SdlInitFlags);
        }
        public void ExecuteProgram()
        {
            _stopwatch.Start();

            while (!_quit)
            {
                var clocks = _device.Step();

                _inputCountdown -= clocks;
                if (_inputCountdown < 0)
                {
                    _inputCountdown += ClocksPerInputCheck;
                    CheckForInput();
                }

                _delayCountdown -= clocks;
                if (_delayCountdown < 0)
                {
                    _delayCountdown += ClocksPerFrame;
                    var msToSleep = _msPerFrame - (_stopwatch.ElapsedTicks / (double)Stopwatch.Frequency) * 1000;
                    if (msToSleep > 0)
                    {
                        SDL2.SDL_Delay((uint)msToSleep);
                    }
                    _stopwatch.Restart();
                }
            }
        }
 public void Dispose()
 {
     _soundOutput?.Dispose();
     SDL2.SDL_DestroyRenderer(_renderer);
     SDL2.SDL_DestroyWindow(_window);
     SDL2.SDL_Quit();
 }
예제 #8
0
 public FrameworkException(string message, bool getSdlError = false) : base(message)
 {
     if (getSdlError)
     {
         SdlError = SDL2.SDL_GetError();
     }
 }
예제 #9
0
        private static void RunGameNoLoop()
        {
            // WARNING!: This function is dependent on the internals of MonoGame; always check the source of truth:
            // https://github.com/MonoGame/MonoGame/blob/develop/MonoGame.Framework/Game.cs

            var type = _game !.GetType();

            var doInitializeMethod = _baseGameType.GetMethod(
                "DoInitialize", BindingFlags.NonPublic | BindingFlags.Instance);

            doInitializeMethod !.Invoke(_game, null);

            var initializedField = _baseGameType.GetField(
                "_initialized",
                BindingFlags.NonPublic | BindingFlags.Instance);

            initializedField !.SetValue(_game, true);

            var beginRunMethod = type.GetMethod(
                "BeginRun", BindingFlags.NonPublic | BindingFlags.Instance);

            beginRunMethod !.Invoke(_game, null);

            var gameTimerField = _baseGameType.GetField(
                "_gameTimer", BindingFlags.NonPublic | BindingFlags.Instance);

            gameTimerField !.SetValue(_game, Stopwatch.StartNew());

            var doUpdateMethod = _baseGameType.GetMethod(
                "DoUpdate", BindingFlags.NonPublic | BindingFlags.Instance);

            doUpdateMethod !.Invoke(_game, new object[] { new GameTime() });

            SDL2.SDL_ShowWindow(_game.Window.Handle);
        }
예제 #10
0
 public static int IMG_SavePNG(IntPtr surface, string file)
 {
     return(INTERNAL_IMG_SavePNG(
                surface,
                SDL2.UTF8_ToNative(file)
                ));
 }
예제 #11
0
        internal FileBasedAudioSource(string filePath, bool decodeWhole)
        {
            RwOpsHandle = SDL2.SDL_RWFromFile(filePath, "rb");

            if (RwOpsHandle == IntPtr.Zero)
            {
                _log.Error($"Failed to initialize RWops from file: {SDL2.SDL_GetError()}");
                return;
            }

            FileSourceHandle = SDL2_nmix.NMIX_NewFileSource(
                RwOpsHandle,
                Path.GetExtension(filePath).TrimStart('.'),
                decodeWhole
                );

            if (FileSourceHandle == IntPtr.Zero)
            {
                _log.Error($"Failed to initialize audio source from file: {SDL2.SDL_GetError()}");
                return;
            }

            unsafe
            {
                Handle = FileSource->source;
            }

            HookSourceCallback();
        }
예제 #12
0
        internal GraphicsManager(Game game, IntPtr sdlRendererHandle)
        {
            _log  = LogManager.GetForCurrentAssembly();
            _game = game;

            SdlRendererHandle = sdlRendererHandle;

            CreateVulkanInstance();

            SDL2.SDL_Vulkan_CreateSurface(
                _game.Window.SdlWindowHandle,
                VulkanInstanceHandle,
                out var surfacePtr
                );

            SdlVulkanSurfaceHandle = new UIntPtr(surfacePtr);
            SdlVulkanSurface       = (SurfaceKhr)typeof(SurfaceKhr).GetConstructor(
                BindingFlags.NonPublic | BindingFlags.Instance,
                null, Type.EmptyTypes, null
                ).Invoke(null);
            typeof(SurfaceKhr).GetField("m", BindingFlags.Instance | BindingFlags.NonPublic)
            .SetValue(SdlVulkanSurface, surfacePtr
                      );

            var physDevs = VulkanInstance.EnumeratePhysicalDevices();

            InitializeVulkan(physDevs[0], SdlVulkanSurface);

            RenderContext = new RenderContext(game);
        }
예제 #13
0
 public static int IMG_SaveJPG(IntPtr surface, string file, int quality)
 {
     return(INTERNAL_IMG_SaveJPG(
                surface,
                SDL2.UTF8_ToNative(file),
                quality
                ));
 }
예제 #14
0
        public void Seek(int milliseconds)
        {
            EnsureFileSourceHandleValid();

            if (SDL2_nmix.NMIX_Seek(FileSourceHandle, milliseconds) < 0)
            {
                _log.Error($"Failed to seek to {milliseconds}ms: {SDL2.SDL_GetError()}");
            }
        }
예제 #15
0
        public void Rewind()
        {
            EnsureFileSourceHandleValid();

            if (SDL2_nmix.NMIX_Rewind(FileSourceHandle) < 0)
            {
                _log.Error($"Failed to rewind the requested audio source: {SDL2.SDL_GetError()}");
            }
        }
예제 #16
0
 public static IntPtr IMG_LoadTexture(
     IntPtr renderer,
     string file
     )
 {
     return(INTERNAL_IMG_LoadTexture(
                renderer,
                SDL2.UTF8_ToNative(file)
                ));
 }
예제 #17
0
        public static KernelModules Setup(KernelModules moduleTypes, object?param = null)
        {
            // Ignore any requested modules... MonoGame is all or nothing

            SetGame(param);
            InitializeReflectedMembers();
            SDL2.LoadApi();

            return(KernelModules.All);
        }
예제 #18
0
        public SDL2(Subsystems subsystems)
        {
            _subsystems = subsystems;

            if (SDL_Init(_subsystems) < 0)
            {
                string message = $"SDL2 could not be initialized! SDL_Error: {SDL2.GetError()}";
                throw new InitializationException(message);
            }
        }
예제 #19
0
        public static string GetName(int playerIndex)
        {
            var controller = ControllerRegistry.Instance.GetControllerInfo(playerIndex);

            if (controller == null)
            {
                return(null);
            }

            return(SDL2.SDL_GameControllerName(controller.InstancePointer));
        }
예제 #20
0
        private void ControllerDisconnected(Window owner, SDL2.SDL_Event ev)
        {
            var instance       = SDL2.SDL_GameControllerFromInstanceID(ev.cdevice.which);
            var controllerInfo = ControllerRegistry.Instance.GetControllerInfoByPointer(instance);

            ControllerRegistry.Instance.Unregister(instance);

            owner.Game.OnControllerDisconnected(
                new ControllerEventArgs(controllerInfo)
                );
        }
예제 #21
0
        public void Quit()
        {
            Audio.Dispose();
            Content.Dispose();

            SDL_mixer.Mix_Quit();
            SDL_gpu.GPU_Quit();
            SDL2.SDL_Quit();

            Environment.Exit(0);
        }
예제 #22
0
 public static void Show(MessageBoxSeverity severity, string title, string message, Window owner = null)
 {
     if (SDL2.SDL_ShowSimpleMessageBox(
             (SDL2.SDL_MessageBoxFlags)severity,
             title,
             message,
             owner?.Handle ?? IntPtr.Zero
             ) < 0)
     {
         Log.Error($"Couldn't show message box: {SDL2.SDL_GetError()}");
     }
 }
예제 #23
0
 public static IntPtr IMG_LoadTyped_RW(
     IntPtr src,
     int freesrc,
     string type
     )
 {
     return(INTERNAL_IMG_LoadTyped_RW(
                src,
                freesrc,
                SDL2.UTF8_ToNative(type)
                ));
 }
예제 #24
0
        public static void AddMapping(string controllerMapping)
        {
            if (string.IsNullOrEmpty(controllerMapping))
            {
                _log.Warning("Tried to add a null or empty controller mapping.");
                return;
            }

            if (SDL2.SDL_GameControllerAddMapping(controllerMapping) < 0)
            {
                _log.Error($"Failed to add a controller mapping: {SDL2.SDL_GetError()}.");
            }
        }
예제 #25
0
        public static BatteryStatus GetBatteryLevel(int playerIndex)
        {
            var controller = ControllerRegistry.Instance.GetControllerInfo(playerIndex);

            if (controller == null)
            {
                return(BatteryStatus.Unknown);
            }

            var joystickInstance = SDL2.SDL_GameControllerGetJoystick(controller.InstancePointer);

            return((BatteryStatus)SDL2.SDL_JoystickCurrentPowerLevel(joystickInstance));
        }
예제 #26
0
        private static void InitializeSdlSystems()
        {
            Console.WriteLine("---");

            Console.WriteLine("Initializing SDL2 core...");
            SDL2.SDL_Init(BootConfig.SdlModules.SdlInitFlags);

            if (BootConfig.EnableSdlGpuDebugging)
            {
                Console.WriteLine("Enabling SDL_gpu debugging...");
                SDL_gpu.GPU_SetDebugLevel(SDL_gpu.GPU_DebugLevelEnum.GPU_DEBUG_LEVEL_MAX);
            }
        }
예제 #27
0
        public static bool IsButtonPressed(int playerIndex, ControllerButton button)
        {
            var controller = ControllerRegistry.Instance.GetControllerInfo(playerIndex);

            if (controller == null)
            {
                return(false);
            }

            return(SDL2.SDL_GameControllerGetButton(
                       controller.InstancePointer,
                       (SDL2.SDL_GameControllerButton)button
                       ) > 0);
        }
예제 #28
0
        internal void Update()
        {
            var currentTime = SDL2.SDL_GetTicks();

            if (currentTime - _lastTime > 1000)
            {
                FPS = _frameCount;

                _lastTime   = currentTime;
                _frameCount = 0;
            }

            _frameCount++;
        }
예제 #29
0
        protected override void FreeNativeResources()
        {
            if (FileSourceHandle != IntPtr.Zero)
            {
                SDL2_nmix.NMIX_FreeFileSource(Handle);
                FileSourceHandle = IntPtr.Zero;
            }

            if (RwOpsHandle != IntPtr.Zero)
            {
                SDL2.SDL_FreeRW(RwOpsHandle);
                RwOpsHandle = IntPtr.Zero;
            }
        }
예제 #30
0
        private void ControllerButtonReleased(Window owner, SDL2.SDL_Event ev)
        {
            var instance   = SDL2.SDL_GameControllerFromInstanceID(ev.cbutton.which);
            var controller = ControllerRegistry.Instance.GetControllerInfoByPointer(instance);

            var button = (ControllerButton)ev.cbutton.button;

            owner.Game.OnControllerButtonReleased(
                new ControllerButtonEventArgs(
                    controller,
                    button
                    )
                );
        }