Beispiel #1
0
        public unsafe Cursor(FileSystemEntry entry, float windowScale)
        {
            var cursorFile = CursorFile.FromFileSystemEntry(entry);

            _animationFrames = cursorFile.AnimationFrames;

            _surfaces = new Sdl2Interop.SDL_Surface[cursorFile.Images.Length];
            _cursors  = new Sdl2Interop.SDL_Cursor[cursorFile.Images.Length];

            for (var i = 0; i < cursorFile.Images.Length; i++)
            {
                var image = cursorFile.Images[i];

                var width  = (int)image.Width;
                var height = (int)image.Height;

                Sdl2Interop.SDL_Surface surface;
                if (windowScale == 1.0f)
                {
                    fixed(byte *pixelsPtr = image.PixelsBgra)
                    {
                        surface = Sdl2Interop.SDL_CreateRGBSurfaceWithFormatFrom(
                            pixelsPtr,
                            width,
                            height,
                            32,
                            width * 4,
                            Sdl2Interop.SDL_PixelFormat.SDL_PIXELFORMAT_ABGR8888);
                    }
                }
                else
                {
                    var scaledWidth  = (int)(windowScale * width);
                    var scaledHeight = (int)(windowScale * height);

                    var scaledImage = Image.LoadPixelData <Bgra32>(image.PixelsBgra, width, height);
                    scaledImage.Mutate(x => x.Resize(scaledWidth, scaledHeight));

                    if (!scaledImage.TryGetSinglePixelSpan(out Span <Bgra32> pixelSpan))
                    {
                        throw new InvalidOperationException("Unable to get image pixelspan.");
                    }

                    fixed(void *pin = &MemoryMarshal.GetReference(pixelSpan))
                    {
                        surface = Sdl2Interop.SDL_CreateRGBSurfaceWithFormatFrom(
                            (byte *)pin,
                            scaledWidth,
                            scaledHeight,
                            32,
                            scaledWidth * 4,
                            Sdl2Interop.SDL_PixelFormat.SDL_PIXELFORMAT_ABGR8888);
                    }
                }

                AddDisposeAction(() => Sdl2Interop.SDL_FreeSurface(surface));

                _surfaces[i] = surface;

                var cursor = Sdl2Interop.SDL_CreateColorCursor(
                    _surfaces[i],
                    (int)(image.HotspotX * windowScale),
                    (int)(image.HotspotY * windowScale));

                AddDisposeAction(() => Sdl2Interop.SDL_FreeCursor(cursor));

                _cursors[i] = cursor;
            }
        }
Beispiel #2
0
        public unsafe Cursor(FileSystemEntry entry, GameWindow window)
        {
            _aniFile = AniFile.FromFileSystemEntry(entry);

            var width  = (int)_aniFile.IconWidth;
            var height = (int)_aniFile.IconHeight;

            _surfaces = new Sdl2Interop.SDL_Surface[_aniFile.Images.Length];
            _cursors  = new Sdl2Interop.SDL_Cursor[_aniFile.Images.Length];

            var windowScale = window.WindowScale;

            for (var i = 0; i < _aniFile.Images.Length; i++)
            {
                var pixels = _aniFile.Images[i].PixelsBgra;

                fixed(byte *pixelsPtr = pixels)
                {
                    var surface = Sdl2Interop.SDL_CreateRGBSurfaceWithFormatFrom(
                        pixelsPtr,
                        width,
                        height,
                        32,
                        width * 4,
                        Sdl2Interop.SDL_PixelFormat.SDL_PIXELFORMAT_ABGR8888);

                    if (windowScale != 1.0f)
                    {
                        var scaledWidth  = (int)(windowScale * width);
                        var scaledHeight = (int)(windowScale * height);

                        var scaledSurface = Sdl2Interop.SDL_CreateRGBSurfaceWithFormat(
                            0,
                            scaledWidth,
                            scaledHeight,
                            32,
                            Sdl2Interop.SDL_PixelFormat.SDL_PIXELFORMAT_ABGR8888);

                        Sdl2Interop.SDL_BlitScaled(
                            surface,
                            new Sdl2Interop.SDL_Rect(0, 0, width, height),
                            scaledSurface,
                            new Sdl2Interop.SDL_Rect(0, 0, scaledWidth, scaledHeight));

                        Sdl2Interop.SDL_FreeSurface(surface);

                        surface = scaledSurface;
                    }

                    AddDisposeAction(() => Sdl2Interop.SDL_FreeSurface(surface));

                    _surfaces[i] = surface;
                }

                var cursor = Sdl2Interop.SDL_CreateColorCursor(
                    _surfaces[i],
                    (int)_aniFile.HotspotX,
                    (int)_aniFile.HotspotY);

                AddDisposeAction(() => Sdl2Interop.SDL_FreeCursor(cursor));

                _cursors[i] = cursor;
            }
        }