示例#1
0
        /// <summary>
        /// Sets up a window and enters the gameloop. (Code after this call won't run until the game has exited.)
        /// </summary>
        public static void Run(float speed = 100f)
        {
            SDL.Init(SDL.InitFlags.EVERYTHING);
            IMG.Init(IMG.InitFlags.EVERYTHING);
            Mix.Init(Mix.InitFlags.EVERYTHING);
            TTF.Init();

            //open window
            SDL.SetHint(SDL.HINT_RENDER_VSYNC, "1");
            SDL.SetHint(SDL.HINT_RENDER_SCALE_QUALITY, "2");

            WindowHandle   = SDL.CreateWindow("HatlessEngine", SDL.WINDOWPOS_UNDEFINED, SDL.WINDOWPOS_UNDEFINED, 800, 600, SDL.WindowFlags.WINDOW_SHOWN | SDL.WindowFlags.WINDOW_RESIZABLE | SDL.WindowFlags.WINDOW_INPUT_FOCUS);
            RendererHandle = SDL.CreateRenderer(WindowHandle, -1, (uint)(SDL.RendererFlags.RENDERER_ACCELERATED | SDL.RendererFlags.RENDERER_PRESENTVSYNC));
            SDL.SetRenderDrawBlendMode(RendererHandle, SDL.BlendMode.BLENDMODE_BLEND);

            Window.SetIcon();

            //add default view that spans the current window
            new View("default", new Rectangle(Point.Zero, Window.Size), new Rectangle(Point.Zero, new Point(1f, 1f)));

            //initialize audio system and let Resources handle sound expiration
            Mix.OpenAudio(44100, SDL.AUDIO_S16SYS, 2, 4096);
            Mix.AllocateChannels((int)(speed * 2));             //might want to dynamically create and remove channels during runtime
            Mix.ChannelFinished(new Mix.ChannelFinishedDelegate(Resources.SoundChannelFinished));
            Mix.HookMusicFinished(new Mix.MusicFinishedDelegate(Resources.MusicFinished));

            //initialize loop
            StepsPerSecond = speed;

            Running = true;

            if (Started != null)
            {
                Started(null, EventArgs.Empty);
            }

            Stopwatch stopWatch = new Stopwatch();

            stopWatch.Start();

            //do a step before the first draw can occur
            Step();

            long lastStepTick = 0;
            long lastDrawTick = 0;
            long lastStepTime = 0;
            long lastDrawTime = 0;

            while (Running)
            {
                //perform step when needed
                if (stopWatch.ElapsedTicks >= lastStepTick + TicksPerStep)
                {
                    if (CatchUpSteps)
                    {
                        lastStepTick = lastStepTick + TicksPerStep;
                    }
                    else
                    {
                        lastStepTick = stopWatch.ElapsedTicks;
                    }
                    Step();

                    _ActualSPS   = (int)(Stopwatch.Frequency / (stopWatch.ElapsedTicks - lastStepTime));
                    lastStepTime = stopWatch.ElapsedTicks;
                }

                //perform draw when ready for a new one
                if (!RenderframeReady && Running && stopWatch.ElapsedTicks >= lastDrawTick + TicksPerDraw)
                {
                    lastDrawTick = lastDrawTick + TicksPerDraw;
                    Draw();

                    _ActualFPS   = (int)(Stopwatch.Frequency / (stopWatch.ElapsedTicks - lastDrawTime));
                    lastDrawTime = stopWatch.ElapsedTicks;
                }
            }

            //cleanup and uninitialization
            Resources.UnloadAllExternalResources();
            Log.CloseAllStreams();
            Input.CloseGamepads();

            SDL.DestroyWindow(WindowHandle);
            WindowHandle = IntPtr.Zero;
            SDL.DestroyRenderer(RendererHandle);
            RendererHandle = IntPtr.Zero;

            Mix.CloseAudio();

            SDL.Quit();
            IMG.Quit();
            Mix.Quit();
            TTF.Quit();
        }
示例#2
0
        static void Main(string[] args)
        {
            SDL.Init(InitFlags.Everything);
            Log.Priorities.SetAll(LogPriority.Verbose);
            Log.OutputFunction = (cat, prio, msg) => {
                Console.WriteLine($"[{prio}] {cat}: {msg}");
            };
            Log.Message(LogCategory.Application, LogPriority.Debug, "Foo and bar!?");
            TTF.Init();
            Events.Watch += (ref Event e) =>
            {
                //Console.WriteLine(e.ToString());
            };

            Console.WriteLine("Registering timer");
            int         callbackCount = 0;
            IDisposable?d             = null;

            d = SDLSharp.Timer.AddTimer(500, n =>
            {
                Console.WriteLine($"{n}: Timer callback {callbackCount++}");
                if (callbackCount > 4 && d != null)
                {
                    Console.WriteLine("I've had it with this callback business!");
                    d.Dispose();
                }
                return(500 * (uint)callbackCount);
            });
            Console.WriteLine($"{d} registered");

            Console.WriteLine("Ok, here we go:");


            Console.WriteLine($"Running SDL version {SDL.RuntimeVersion} {SDL.RuntimeRevision} {SDL.RuntimeRevisionNumber}");
            Console.WriteLine($"\tSDL_image version {Image.RuntimeVersion}");
            Console.WriteLine($"\tSDL_ttf version {TTF.RuntimeVersion}");
            Console.WriteLine($"Video drivers: {string.Join("; ", Video.Drivers)}");
            Console.WriteLine($"Audio drivers: {string.Join("; ", Audio.Drivers)}");
            Console.WriteLine($"Audio input devices: {string.Join("; ", Audio.InputDevices)}");
            Console.WriteLine($"Audio output devices: {string.Join("; ", Audio.InputDevices)}");

            if (Clipboard.HasText())
            {
                Console.Write("Clipboard contains: ");
                Console.WriteLine(Clipboard.GetText());
            }
            else
            {
                Console.Write("Clipboard is empty. An empty string looks like: ");
                Console.WriteLine(Clipboard.GetText());
            }

            foreach (var display in Video.Displays)
            {
                Console.WriteLine($"Display {display.Index}");
                Console.WriteLine($"    Name={display.Name}");
                Console.WriteLine($"    Bounds={display.Bounds}");
                Console.WriteLine($"    UsableBounds={display.UsableBounds}");
                Console.WriteLine($"    DPI={display.DPI}");
                Console.WriteLine($"    Modes.Current={display.Modes.Current}");
                Console.WriteLine($"    Modes.Desktop={display.Modes.Desktop}");
                for (int i = 0; i < display.Modes.Count; ++i)
                {
                    Console.WriteLine($"    Modes.[{i}]={display.Modes[i]}");
                }
            }
            for (int i = 0; i < Renderer.Drivers.Count; ++i)
            {
                var ri = Renderer.Drivers[i];
                Console.WriteLine($"Render driver {i}");
                Console.WriteLine($"    Name={ri.Name}");
                Console.WriteLine($"    Flags={ri.Flags}");
                Console.WriteLine($"    MaxTextureWidth={ri.MaxTextureWidth}");
                Console.WriteLine($"    MaxTextureHeight={ri.MaxTextureHeight}");
                for (int j = 0; j < ri.Formats.Count; ++j)
                {
                    Console.WriteLine($"    Formats.[{j}]={PixelFormat.GetName(ri.Formats[j])}");
                }
            }

            foreach (var joy in Joystick.Devices)
            {
                Console.WriteLine($"{joy}");
                Console.WriteLine($"\tGuid={joy.Guid}");
                Console.WriteLine($"\tName={joy.Name}");
                Console.WriteLine($"\tIsController={joy.IsController}");
                using (var j = joy.Open())
                {
                    Console.WriteLine($"\t\tOpened {j}");
                    Console.WriteLine($"\t\tID={j.ID}");
                    Console.WriteLine($"\t\tName={j.Name}");
                    Console.WriteLine($"\t\tGuid={j.Guid}");
                    Console.WriteLine($"\t\tPowerLevel={j.PowerLevel}");
                    Console.WriteLine($"\t\tNumAxes={j.Axes.Count}");
                    Console.WriteLine($"\t\tButtons={j.Buttons.Count}");
                    Console.WriteLine($"\t\tHats={j.Hats.Count}");
                    Console.WriteLine($"\t\tBalls={j.Balls.Count}");
                }

                if (joy.IsController)
                {
                    using (var c = joy.OpenController())
                    {
                        foreach (var axis in Enum.GetValues(typeof(GameControllerAxis)).Cast <GameControllerAxis>())
                        {
                            if (axis == GameControllerAxis.Invalid || axis == GameControllerAxis.Max)
                            {
                                continue;
                            }

                            var b = c.Axes.GetBind(axis);
                            Console.WriteLine($"\t\tAxis[{axis}/{GameController.AxisName(axis)}].Bind={b}");
                        }
                        foreach (var btn in Enum.GetValues(typeof(GameControllerButton)).Cast <GameControllerButton>())
                        {
                            if (btn == GameControllerButton.Invalid || btn == GameControllerButton.Max)
                            {
                                continue;
                            }
                            var b = c.Buttons.GetBind(btn);
                            Console.WriteLine($"\t\tButtons[{btn}/{GameController.ButtonName(btn)}].Bind={b}");
                        }
                        Console.WriteLine($"\t\tMapping={c.Mapping}");
                    }
                }
            }

            foreach (var dev in Audio.OutputDevices)
            {
                var fmt     = new AudioStreamFormat(44000, AudioDataFormat.Float32Bit, 1, 0, 1024);
                var changes = AllowedAudioStreamChange.Any;
                Console.Write($"Requesting {fmt} from audio output '{dev}' allowing changes to {changes}...");

                try
                {
                    using (var a = Audio.OpenOutput(dev, changes, fmt, out var obtained))
                    {
                        Console.WriteLine($"\tgot {obtained}");
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"\tFailed w/ error: {ex}");
                }
            }


            foreach (var dev in Audio.InputDevices)
            {
                var fmt     = new AudioStreamFormat(44000, AudioDataFormat.Float32Bit, 1, 0, 1024);
                var changes = AllowedAudioStreamChange.Any;
                Console.Write($"Requesting {fmt} from audio input '{dev}' allowing changes to {changes}...");

                try
                {
                    using (var a = Audio.OpenInput(dev, changes, fmt, out var obtained))
                    {
                        Console.WriteLine($"\tgot {a} with format {obtained}");
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"\tFailed w/ error: {ex}");
                }
            }

            Mixer.Open(44100, AudioDataFormat.Float32Bit, 2, 1024);
            Mixer.Init(MixerLoaders.MP3);

            Console.WriteLine($"Opened the mixer hz={Mixer.DeviceFrequency} f={Mixer.DeviceFormat} ch={Mixer.DeviceChannels}");
            Console.WriteLine($"\tAvailable music decoders {string.Join("; ", MusicTrack.Decoders)}");
            Console.WriteLine($"\tAvailable chunk decoders {string.Join("; ", MixerChunk.Decoders)}");


            PrintChannels();
            Mixer.Channels.Count = 8;
            PrintChannels();


            using var caketown = MusicTrack.Load("./assets/Caketown 1.mp3");
            Console.WriteLine($"Loaded {caketown}");
            Task.Run(async() =>
            {
                Mixer.Music.Play(caketown);

                Mixer.Music.Finished += (se, ev) => Console.WriteLine("Music finished");

                await Task.Delay(1000);
                Mixer.Music.Pause();
                Console.WriteLine($"{caketown} paused");
                await Task.Delay(1000);
                Mixer.Music.Resume();
                Console.WriteLine($"{caketown} resumed");
                await Task.Delay(1000);
                Mixer.Music.Rewind();
                Console.WriteLine($"{caketown} rewound");
                await Task.Delay(1000);
                Console.WriteLine($"{caketown} fading out");
                Mixer.Music.FadeOut(1000);
                Console.WriteLine($"{caketown} faded out");
                Mixer.Music.Halt();
                Console.WriteLine($"{caketown} halted");
            });

            using var alarm = MixerChunk.Load("./assets/wobbleboxx.com/Rise01.wav");

            var flags = WindowFlags.Shown | WindowFlags.Resizable;

            using (var window = Video.CreateWindow("Foo änd bar", Window.UndefinedPosition, Window.UndefinedPosition, 600, 400, flags))
                using (var renderer = Renderer.Create(window, -1, RendererFlags.Accelerated))
                {
                    Console.WriteLine($"Created window {window}");

                    Mixer.Channels.ChannelFinished += (se, ev) => Console.WriteLine($"{ev.Channel} finished");
                    window.SetHitTest((Window w, in SDLSharp.Point p) =>
                    {
                        Console.WriteLine($"Hit test at {(System.Drawing.Point)p} in window '{w}'");
                        Events.Current.Push((Action)(() =>
                        {
                            if (Mixer.Channels.Play(alarm, 1))
                            {
                                Console.Write("Playing sound ");
                            }
                            else
                            {
                                Console.Write("NOT playing sound ");
                            }
                            PrintChannels();
                        }));
                        return(HitTestResult.Normal);
                    });