mirror of
https://github.com/love2d/megasource.git
synced 2026-08-21 05:02:11 +02:00
Add SDL3 3.1.1-preview
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#if defined(SDL_VIDEO_DRIVER_WINDOWS) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
|
||||
|
||||
#include "SDL_windowsvideo.h"
|
||||
#include "SDL_windowsshape.h"
|
||||
|
||||
|
||||
static void AddRegion(HRGN *mask, int x1, int y1, int x2, int y2)
|
||||
{
|
||||
HRGN region = CreateRectRgn(x1, y1, x2, y2);
|
||||
if (*mask) {
|
||||
CombineRgn(*mask, *mask, region, RGN_OR);
|
||||
DeleteObject(region);
|
||||
} else {
|
||||
*mask = region;
|
||||
}
|
||||
}
|
||||
|
||||
static HRGN GenerateSpanListRegion(SDL_Surface *shape, int offset_x, int offset_y)
|
||||
{
|
||||
HRGN mask = NULL;
|
||||
int x, y;
|
||||
int span_start = -1;
|
||||
|
||||
for (y = 0; y < shape->h; ++y) {
|
||||
const Uint8 *a = (const Uint8 *)shape->pixels + y * shape->pitch;
|
||||
for (x = 0; x < shape->w; ++x) {
|
||||
if (*a == SDL_ALPHA_TRANSPARENT) {
|
||||
if (span_start != -1) {
|
||||
AddRegion(&mask, offset_x + span_start, offset_y + y, offset_x + x, offset_y + y + 1);
|
||||
span_start = -1;
|
||||
}
|
||||
} else {
|
||||
if (span_start == -1) {
|
||||
span_start = x;
|
||||
}
|
||||
}
|
||||
a += 4;
|
||||
}
|
||||
if (span_start != -1) {
|
||||
/* Add the final span */
|
||||
AddRegion(&mask, offset_x + span_start, offset_y + y, offset_x + x, offset_y + y + 1);
|
||||
span_start = -1;
|
||||
}
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
int WIN_UpdateWindowShape(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surface *shape)
|
||||
{
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
HRGN mask = NULL;
|
||||
|
||||
/* Generate a set of spans for the region */
|
||||
if (shape) {
|
||||
SDL_Surface *stretched = NULL;
|
||||
RECT rect;
|
||||
|
||||
if (shape->w != window->w || shape->h != window->h) {
|
||||
stretched = SDL_CreateSurface(window->w, window->h, SDL_PIXELFORMAT_ARGB32);
|
||||
if (!stretched) {
|
||||
return -1;
|
||||
}
|
||||
if (SDL_SoftStretch(shape, NULL, stretched, NULL, SDL_SCALEMODE_LINEAR) < 0) {
|
||||
SDL_DestroySurface(stretched);
|
||||
return -1;
|
||||
}
|
||||
shape = stretched;
|
||||
}
|
||||
|
||||
rect.top = 0;
|
||||
rect.left = 0;
|
||||
rect.bottom = 0;
|
||||
rect.right = 0;
|
||||
if (!(SDL_GetWindowFlags(data->window) & SDL_WINDOW_BORDERLESS)) {
|
||||
WIN_AdjustWindowRectForHWND(data->hwnd, &rect, 0);
|
||||
}
|
||||
|
||||
mask = GenerateSpanListRegion(shape, -rect.left, -rect.top);
|
||||
|
||||
if (!(SDL_GetWindowFlags(data->window) & SDL_WINDOW_BORDERLESS)) {
|
||||
/* Add the window borders */
|
||||
/* top */
|
||||
AddRegion(&mask, 0, 0, -rect.left + shape->w + rect.right + 1, -rect.top + 1);
|
||||
/* left */
|
||||
AddRegion(&mask, 0, -rect.top, -rect.left + 1, -rect.top + shape->h + 1);
|
||||
/* right */
|
||||
AddRegion(&mask, -rect.left + shape->w, -rect.top, -rect.left + shape->w + rect.right + 1, -rect.top + shape->h + 1);
|
||||
/* bottom */
|
||||
AddRegion(&mask, 0, -rect.top + shape->h, -rect.left + shape->w + rect.right + 1, -rect.top + shape->h + rect.bottom + 1);
|
||||
}
|
||||
|
||||
if (stretched) {
|
||||
SDL_DestroySurface(stretched);
|
||||
}
|
||||
}
|
||||
if (!SetWindowRgn(data->hwnd, mask, TRUE)) {
|
||||
return WIN_SetError("SetWindowRgn failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* defined(SDL_VIDEO_DRIVER_WINDOWS) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) */
|
||||
Reference in New Issue
Block a user