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; } }
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; } }