Compare commits
142
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9836d15e7 | ||
|
|
3146374e4a | ||
|
|
1d852d1c28 | ||
|
|
6ad5a966ea | ||
|
|
a65111bd2d | ||
|
|
c44d37b5cf | ||
|
|
f36d683b61 | ||
|
|
5bdf7bc625 | ||
|
|
38e0094637 | ||
|
|
ba38fda752 | ||
|
|
14eebdab3c | ||
|
|
686c18026b | ||
|
|
6db23faa44 | ||
|
|
6570d9e23f | ||
|
|
2bb0eb4641 | ||
|
|
afeeef9cf5 | ||
|
|
398bacbac3 | ||
|
|
f9435eab16 | ||
|
|
66ac6f4ea7 | ||
|
|
4151df83fe | ||
|
|
00d4f1c2c4 | ||
|
|
1c19bee000 | ||
|
|
639c7a1e52 | ||
|
|
c9889fb013 | ||
|
|
1edb3283b0 | ||
|
|
3e1cebed3c | ||
|
|
66d87bf0e1 | ||
|
|
235e4870af | ||
|
|
8ef0a07a52 | ||
|
|
26d1eadda3 | ||
|
|
39a0fab4d7 | ||
|
|
67141e5079 | ||
|
|
641201a99a | ||
|
|
7b28fb29bd | ||
|
|
ecb72142fd | ||
|
|
9859c05178 | ||
|
|
07c3b3fb7c | ||
|
|
9343246616 | ||
|
|
b55059b487 | ||
|
|
55b599d693 | ||
|
|
2eb5bff91a | ||
|
|
be6ab7f9a6 | ||
|
|
eb974470ec | ||
|
|
f0e7000f92 | ||
|
|
d2ab01b8bb | ||
|
|
f5246d0181 | ||
|
|
b8c802632b | ||
|
|
1725d6b049 | ||
|
|
5ed21d1ccb | ||
|
|
7a34e14c8e | ||
|
|
1a8e667f3d | ||
|
|
d31d98d436 | ||
|
|
56d43ee296 | ||
|
|
1f21aae242 | ||
|
|
5e85a29e75 | ||
|
|
f201b64ffe | ||
|
|
4f9723ece7 | ||
|
|
53dbe1862e | ||
|
|
e7489a0931 | ||
|
|
4b2aa3f102 | ||
|
|
272b073323 | ||
|
|
d310b5679f | ||
|
|
afc1d9122b | ||
|
|
af2279b286 | ||
|
|
059af5265a | ||
|
|
e610529e84 | ||
|
|
74df61530f | ||
|
|
3c36718348 | ||
|
|
b36252b120 | ||
|
|
ead4a032d3 | ||
|
|
cf1eb95fb1 | ||
|
|
34691de22b | ||
|
|
874ca5a678 | ||
|
|
8d5984464e | ||
|
|
2a6baf50e9 | ||
|
|
6c9c2a9ac2 | ||
|
|
8605624158 | ||
|
|
b537380065 | ||
|
|
b2c3e6fade | ||
|
|
309d1481a4 | ||
|
|
2fb6abb9ad | ||
|
|
cd0cf8b855 | ||
|
|
2bc3ec44b1 | ||
|
|
e4475d1868 | ||
|
|
6a71328638 | ||
|
|
6701f938f7 | ||
|
|
1c09a7117a | ||
|
|
9eb50a906a | ||
|
|
027d46f03a | ||
|
|
3416296366 | ||
|
|
01c3ccd541 | ||
|
|
3c08172d06 | ||
|
|
d0c2d8bc40 | ||
|
|
33eb167da8 | ||
|
|
4b4f6b3e22 | ||
|
|
2163887f29 | ||
|
|
c0f78dee5e | ||
|
|
17e6208c1b | ||
|
|
157f894d5d | ||
|
|
a220e7c422 | ||
|
|
2442c85cb8 | ||
|
|
5b951141d2 | ||
|
|
15fd3fcdc2 | ||
|
|
45b01d16b1 | ||
|
|
433810c58d | ||
|
|
916ddb1ef8 | ||
|
|
1c75cb4f8a | ||
|
|
26e946ef08 | ||
|
|
035518d065 | ||
|
|
40b1eac541 | ||
|
|
bfab0a968f | ||
|
|
f0a8e09f7c | ||
|
|
2e4c12cd2c | ||
|
|
3e47181800 | ||
|
|
8436ce98b4 | ||
|
|
a8f0eb4c33 | ||
|
|
069eb012aa | ||
|
|
7d8a6f1603 | ||
|
|
d63b3376a4 | ||
|
|
52146cf067 | ||
|
|
46a51b4298 | ||
|
|
4f488b9be2 | ||
|
|
f48a96a976 | ||
|
|
39bb71c442 | ||
|
|
177fb9cb6c | ||
|
|
fc536dcb7e | ||
|
|
1caae3e9e4 | ||
|
|
22a87a22ca | ||
|
|
6be87ceb33 | ||
|
|
ab44451578 | ||
|
|
52ac07d327 | ||
|
|
0809be4ec5 | ||
|
|
24693ac285 | ||
|
|
92cadaf917 | ||
|
|
d2eb72fd14 | ||
|
|
b4d733619a | ||
|
|
ed2c004c8a | ||
|
|
6421f12d7f | ||
|
|
ee49025f80 | ||
|
|
5925c27efb | ||
|
|
aa00738a21 | ||
|
|
5330041ea9 |
No files matched your search
@@ -20,7 +20,6 @@ class AppleArch(Enum):
|
||||
class MsvcArch(Enum):
|
||||
X86 = "x86"
|
||||
X64 = "x64"
|
||||
Arm32 = "arm"
|
||||
Arm64 = "arm64"
|
||||
|
||||
|
||||
@@ -97,7 +96,6 @@ class JobSpec:
|
||||
msvc_static_crt: bool = False
|
||||
clang_cl: bool = False
|
||||
gdk: bool = False
|
||||
uwp: bool = False
|
||||
vita_gles: Optional[VitaGLES] = None
|
||||
watcom_platform: Optional[WatcomPlatform] = None
|
||||
|
||||
@@ -113,9 +111,7 @@ JOB_SPECS = {
|
||||
"msvc-static-x64": JobSpec(name="Windows (MSVC, static VCRT, x64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-x64", msvc_arch=MsvcArch.X64, msvc_static_crt=True, ),
|
||||
"msvc-clang-x64": JobSpec(name="Windows (MSVC, clang-cl x64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-clang-cl-x64", msvc_arch=MsvcArch.X64, clang_cl=True, ),
|
||||
"msvc-clang-x86": JobSpec(name="Windows (MSVC, clang-cl x86)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-clang-cl-x86", msvc_arch=MsvcArch.X86, clang_cl=True, ),
|
||||
"msvc-arm32": JobSpec(name="Windows (MSVC, ARM)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-arm32", msvc_arch=MsvcArch.Arm32, ),
|
||||
"msvc-arm64": JobSpec(name="Windows (MSVC, ARM64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-arm64", msvc_arch=MsvcArch.Arm64, ),
|
||||
"msvc-uwp-x64": JobSpec(name="UWP (MSVC, x64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-UWP", msvc_arch=MsvcArch.X64, msvc_project="VisualC-WinRT/SDL-UWP.sln", uwp=True, ),
|
||||
"msvc-gdk-x64": JobSpec(name="GDK (MSVC, x64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-GDK", msvc_arch=MsvcArch.X64, msvc_project="VisualC-GDK/SDL.sln", gdk=True, no_cmake=True, ),
|
||||
"ubuntu-22.04": JobSpec(name="Ubuntu 22.04", os=JobOs.Ubuntu22_04, platform=SdlPlatform.Linux, artifact="SDL-ubuntu22.04", autotools=True),
|
||||
"steamrt-sniper": JobSpec(name="Steam Linux Runtime (Sniper)", os=JobOs.UbuntuLatest, platform=SdlPlatform.Linux, artifact="SDL-slrsniper", container="registry.gitlab.steamos.cloud/steamrt/sniper/sdk:beta", ),
|
||||
@@ -367,10 +363,7 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
||||
"-DCMAKE_EXE_LINKER_FLAGS=-DEBUG",
|
||||
"-DCMAKE_SHARED_LINKER_FLAGS=-DEBUG",
|
||||
))
|
||||
if spec.uwp:
|
||||
job.cmake_arguments.append("'-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded$<$<CONFIG:Debug>:Debug>DLL'")
|
||||
else:
|
||||
job.cmake_arguments.append("'-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded$<$<CONFIG:Debug>:Debug>'")
|
||||
job.cmake_arguments.append("'-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded$<$<CONFIG:Debug>:Debug>'")
|
||||
|
||||
if spec.clang_cl:
|
||||
job.cmake_arguments.extend((
|
||||
@@ -402,21 +395,10 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
||||
job.msvc_vcvars_arch = "x64_x86"
|
||||
case MsvcArch.X64:
|
||||
job.msvc_vcvars_arch = "x64"
|
||||
case MsvcArch.Arm32:
|
||||
job.msvc_vcvars_arch = "x64_arm"
|
||||
job.msvc_vcvars_sdk = "10.0.22621.0" # 10.0.26100.0 dropped ARM32 um and ucrt libraries
|
||||
job.run_tests = False
|
||||
case MsvcArch.Arm64:
|
||||
job.msvc_vcvars_arch = "x64_arm64"
|
||||
job.run_tests = False
|
||||
if spec.uwp:
|
||||
job.build_tests = False
|
||||
job.cmake_arguments.extend((
|
||||
"-DCMAKE_SYSTEM_NAME=WindowsStore",
|
||||
"-DCMAKE_SYSTEM_VERSION=10.0",
|
||||
))
|
||||
job.msvc_project_flags.append("-p:WindowsTargetPlatformVersion=10.0.17763.0")
|
||||
elif spec.gdk:
|
||||
if spec.gdk:
|
||||
job.setup_gdk_folder = "VisualC-GDK"
|
||||
else:
|
||||
match spec.msvc_arch:
|
||||
@@ -656,7 +638,7 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
||||
match spec.platform:
|
||||
case SdlPlatform.FreeBSD:
|
||||
job.cpactions_os = "freebsd"
|
||||
job.cpactions_version = "14.2"
|
||||
job.cpactions_version = "14.3"
|
||||
job.cpactions_arch = "x86-64"
|
||||
job.cpactions_setup_cmd = "sudo pkg update"
|
||||
job.cpactions_install_cmd = "sudo pkg install -y cmake ninja pkgconf libXcursor libXext libXinerama libXi libXfixes libXrandr libXScrnSaver libXxf86vm wayland wayland-protocols libxkbcommon mesa-libs libglvnd evdev-proto libinotify alsa-lib jackit pipewire pulseaudio sndio dbus zh-fcitx ibus libudev-devd"
|
||||
@@ -672,10 +654,10 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
||||
job.cpactions_install_cmd = "sudo -E pkgin -y install cmake dbus pkgconf ninja-build pulseaudio libxkbcommon wayland wayland-protocols libinotify libusb1"
|
||||
case SdlPlatform.OpenBSD:
|
||||
job.cpactions_os = "openbsd"
|
||||
job.cpactions_version = "7.4"
|
||||
job.cpactions_version = "7.7"
|
||||
job.cpactions_arch = "x86-64"
|
||||
job.cpactions_setup_cmd = "sudo pkg_add -u"
|
||||
job.cpactions_install_cmd = "sudo pkg_add cmake ninja pkgconf wayland wayland-protocols xwayland libxkbcommon libinotify pulseaudio dbus ibus"
|
||||
job.cpactions_install_cmd = "sudo pkg_add cmake ninja pkgconf wayland wayland-protocols libxkbcommon libinotify pulseaudio dbus ibus"
|
||||
case SdlPlatform.Watcom:
|
||||
match spec.watcom_platform:
|
||||
case WatcomPlatform.OS2:
|
||||
|
||||
@@ -264,7 +264,7 @@ jobs:
|
||||
- name: 'Build (cross-platform-actions, BSD)'
|
||||
id: cpactions
|
||||
if: ${{ matrix.platform.cpactions }}
|
||||
uses: cross-platform-actions/action@v0.27.0
|
||||
uses: cross-platform-actions/action@v0.29.0
|
||||
with:
|
||||
operating_system: '${{ matrix.platform.cpactions-os }}'
|
||||
architecture: '${{ matrix.platform.cpactions-arch }}'
|
||||
|
||||
@@ -23,7 +23,8 @@ manpageheaderfiletext = Defined in %fname%
|
||||
# A handful of others we fix up in the header itself with /* WIKI CATEGORY: x */ comments.
|
||||
headercategoryeval = s/\ASDL_config_.*?\.h\Z//; s/\ASDL_test_.*?\.h\Z//; s/\ASDL_?(.*?)\.h\Z/$1/; ucfirst();
|
||||
|
||||
quickrefenabled = 0 # !!! FIXME: maybe later, but there are probably documentation gaps to fix first.
|
||||
# !!! FIXME: maybe later, but there are probably documentation gaps to fix first.
|
||||
quickrefenabled = 0
|
||||
quickrefcategoryorder = Init,Hints,Error,Version,Properties,Log,Video,Events,Keyboard,Mouse,Touch,Gesture,GameController,Joystick,Haptic,Audio,Timer,Render,LoadSO,Thread,Mutex,Atomic,Filesystem,RWOPS,Pixels,Surface,Blendmode,Rect,Clipboard,Messagebox,Vulkan,Metal,Platform,Power,Sensor,Bits,Endian,Assert,CPUInfo,Locale,System,Misc,GUID,Main,Stdinc
|
||||
quickreftitle = SDL2 API Quick Reference
|
||||
quickrefurl = https://libsdl.org/
|
||||
|
||||
+2
-2
@@ -88,8 +88,8 @@ endif()
|
||||
|
||||
# See docs/release_checklist.md
|
||||
set(SDL_MAJOR_VERSION 2)
|
||||
set(SDL_MINOR_VERSION 32)
|
||||
set(SDL_MICRO_VERSION 10)
|
||||
set(SDL_MINOR_VERSION 33)
|
||||
set(SDL_MICRO_VERSION 0)
|
||||
set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}")
|
||||
|
||||
# Set defaults preventing destination file conflicts
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@
|
||||
|
||||
LIBNAME = SDL2
|
||||
MAJOR_VERSION = 2
|
||||
MINOR_VERSION = 32
|
||||
MICRO_VERSION = 10
|
||||
MINOR_VERSION = 33
|
||||
MICRO_VERSION = 0
|
||||
VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
|
||||
DESCRIPTION = Simple DirectMedia Layer 2
|
||||
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@
|
||||
|
||||
LIBNAME = SDL2
|
||||
MAJOR_VERSION = 2
|
||||
MINOR_VERSION = 32
|
||||
MICRO_VERSION = 10
|
||||
MINOR_VERSION = 33
|
||||
MICRO_VERSION = 0
|
||||
VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
|
||||
|
||||
LIBHOME = .
|
||||
|
||||
@@ -371,6 +371,7 @@
|
||||
<TargetPlatformVersion>10.0.16299.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.16299.0</TargetPlatformMinVersion>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.0.0</WindowsTargetPlatformMinVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@@ -391,7 +392,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
@@ -603,4 +604,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -19,10 +19,10 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.32.10</string>
|
||||
<string>2.33.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>SDLX</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>2.32.10</string>
|
||||
<string>2.33.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -9728,8 +9728,8 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEPLOYMENT_POSTPROCESSING = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 3201.0.0;
|
||||
DYLIB_CURRENT_VERSION = 3201.10.0;
|
||||
DYLIB_COMPATIBILITY_VERSION = 3301.0.0;
|
||||
DYLIB_CURRENT_VERSION = 3301.0.0;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_ALTIVEC_EXTENSIONS = YES;
|
||||
@@ -9770,7 +9770,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_LINK_OBJC_RUNTIME = NO;
|
||||
MARKETING_VERSION = 2.32.10;
|
||||
MARKETING_VERSION = 2.33.0;
|
||||
OTHER_LDFLAGS = "-liconv";
|
||||
};
|
||||
name = Release;
|
||||
@@ -9813,8 +9813,8 @@
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DYLIB_COMPATIBILITY_VERSION = 3201.0.0;
|
||||
DYLIB_CURRENT_VERSION = 3201.10.0;
|
||||
DYLIB_COMPATIBILITY_VERSION = 3301.0.0;
|
||||
DYLIB_CURRENT_VERSION = 3301.0.0;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
@@ -9856,7 +9856,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_LINK_OBJC_RUNTIME = NO;
|
||||
MARKETING_VERSION = 2.32.10;
|
||||
MARKETING_VERSION = 2.33.0;
|
||||
OTHER_LDFLAGS = "-liconv";
|
||||
};
|
||||
name = Debug;
|
||||
@@ -10062,8 +10062,8 @@
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
DYLIB_COMPATIBILITY_VERSION = 3201.0.0;
|
||||
DYLIB_CURRENT_VERSION = 3201.10.0;
|
||||
DYLIB_COMPATIBILITY_VERSION = 3301.0.0;
|
||||
DYLIB_CURRENT_VERSION = 3301.0.0;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
@@ -10114,8 +10114,8 @@
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
DYLIB_COMPATIBILITY_VERSION = 3201.0.0;
|
||||
DYLIB_CURRENT_VERSION = 3201.10.0;
|
||||
DYLIB_COMPATIBILITY_VERSION = 3301.0.0;
|
||||
DYLIB_CURRENT_VERSION = 3301.0.0;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Title SDL 2.32.10
|
||||
Title SDL 2.33.0
|
||||
Version 1
|
||||
Description SDL Library for Mac OS X (http://www.libsdl.org)
|
||||
DefaultLocation /Library/Frameworks
|
||||
|
||||
@@ -11,15 +11,15 @@ android {
|
||||
if (buildAsApplication) {
|
||||
namespace "org.libsdl.app"
|
||||
}
|
||||
compileSdkVersion 34
|
||||
compileSdkVersion 35
|
||||
defaultConfig {
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 34
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 35
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
arguments "APP_PLATFORM=android-19"
|
||||
arguments "APP_PLATFORM=android-21"
|
||||
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
||||
}
|
||||
// cmake {
|
||||
|
||||
@@ -60,8 +60,8 @@ import java.util.Locale;
|
||||
public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener {
|
||||
private static final String TAG = "SDL";
|
||||
private static final int SDL_MAJOR_VERSION = 2;
|
||||
private static final int SDL_MINOR_VERSION = 32;
|
||||
private static final int SDL_MICRO_VERSION = 10;
|
||||
private static final int SDL_MINOR_VERSION = 33;
|
||||
private static final int SDL_MICRO_VERSION = 0;
|
||||
/*
|
||||
// Display InputType.SOURCE/CLASS of events and devices
|
||||
//
|
||||
|
||||
@@ -6,7 +6,7 @@ buildscript {
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.1.1'
|
||||
classpath 'com.android.tools.build:gradle:8.6.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#Thu Nov 11 18:20:34 PST 2021
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
+131
-40
@@ -37,6 +37,8 @@ logger = logging.getLogger(__name__)
|
||||
GIT_HASH_FILENAME = ".git-hash"
|
||||
REVISION_TXT = "REVISION.txt"
|
||||
|
||||
RE_ILLEGAL_MINGW_LIBRARIES = re.compile(r"(?:lib)?(?:gcc|(?:std)?c[+][+]|(?:win)?pthread).*", flags=re.I)
|
||||
|
||||
|
||||
def safe_isotime_to_datetime(str_isotime: str) -> datetime.datetime:
|
||||
try:
|
||||
@@ -339,6 +341,12 @@ class ArchiveFileTree:
|
||||
def add_file(self, file: NodeInArchive):
|
||||
self._tree[file.arcpath] = file
|
||||
|
||||
def __iter__(self) -> typing.Iterable[NodeInArchive]:
|
||||
yield from self._tree.values()
|
||||
|
||||
def __contains__(self, value: str) -> bool:
|
||||
return value in self._tree
|
||||
|
||||
def get_latest_mod_time(self) -> datetime.datetime:
|
||||
return max(item.time for item in self._tree.values() if item.time)
|
||||
|
||||
@@ -526,6 +534,16 @@ class SourceCollector:
|
||||
return path_times
|
||||
|
||||
|
||||
class AndroidApiVersion:
|
||||
def __init__(self, name: str, ints: tuple[int, ...]):
|
||||
self.name = name
|
||||
self.ints = ints
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<{self.name} ({'.'.join(str(v) for v in self.ints)})>"
|
||||
|
||||
ANDROID_ABI_EXTRA_LINK_OPTIONS = {}
|
||||
|
||||
class Releaser:
|
||||
def __init__(self, release_info: dict, commit: str, revision: str, root: Path, dist_path: Path, section_printer: SectionPrinter, executer: Executer, cmake_generator: str, deps_path: Path, overwrite: bool, github: bool, fast: bool):
|
||||
self.release_info = release_info
|
||||
@@ -586,12 +604,22 @@ class Releaser:
|
||||
def create_source_archives(self) -> None:
|
||||
source_collector = SourceCollector(root=self.root, commit=self.commit, executer=self.executer, filter=self._path_filter)
|
||||
print(f"Collecting sources of {self.project}...")
|
||||
archive_tree = source_collector.get_archive_file_tree()
|
||||
archive_tree: ArchiveFileTree = source_collector.get_archive_file_tree()
|
||||
latest_mod_time = archive_tree.get_latest_mod_time()
|
||||
archive_tree.add_file(NodeInArchive.from_text(arcpath=REVISION_TXT, text=f"{self.revision}\n", time=latest_mod_time))
|
||||
archive_tree.add_file(NodeInArchive.from_text(arcpath=f"{GIT_HASH_FILENAME}", text=f"{self.commit}\n", time=latest_mod_time))
|
||||
archive_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["source"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=latest_mod_time)
|
||||
|
||||
if "Makefile.am" in archive_tree:
|
||||
patched_time = latest_mod_time + datetime.timedelta(minutes=1)
|
||||
print(f"Makefile.am detected -> touching aclocal.m4, */Makefile.in, configure")
|
||||
for node_data in archive_tree:
|
||||
arc_name = os.path.basename(node_data.arcpath)
|
||||
arc_name_we, arc_name_ext = os.path.splitext(arc_name)
|
||||
if arc_name in ("aclocal.m4", "configure", "Makefile.in"):
|
||||
print(f"Bumping time of {node_data.arcpath}")
|
||||
node_data.time = patched_time
|
||||
|
||||
archive_base = f"{self.project}-{self.version}"
|
||||
zip_path = self.dist_path / f"{archive_base}.zip"
|
||||
tgz_path = self.dist_path / f"{archive_base}.tar.gz"
|
||||
@@ -668,6 +696,15 @@ class Releaser:
|
||||
def git_hash_data(self) -> bytes:
|
||||
return f"{self.commit}\n".encode()
|
||||
|
||||
def verify_mingw_library(self, triplet: str, path: Path):
|
||||
objdump_output = self.executer.check_output([f"{triplet}-objdump", "-p", str(path)])
|
||||
libraries = re.findall(r"DLL Name: ([^\n]+)", objdump_output)
|
||||
logger.info("%s (%s) libraries: %r", path, triplet, libraries)
|
||||
illegal_libraries = list(filter(RE_ILLEGAL_MINGW_LIBRARIES.match, libraries))
|
||||
logger.error("Detected 'illegal' libraries: %r", illegal_libraries)
|
||||
if illegal_libraries:
|
||||
raise Exception(f"{path} links to illegal libraries: {illegal_libraries}")
|
||||
|
||||
def create_mingw_archives(self) -> None:
|
||||
build_type = "Release"
|
||||
build_parent_dir = self.root / "build-mingw"
|
||||
@@ -764,7 +801,6 @@ class Releaser:
|
||||
f"--includedir=${{prefix}}/include",
|
||||
f"--libdir=${{prefix}}/lib",
|
||||
f"--bindir=${{prefix}}/bin",
|
||||
f"--exec-prefix=${{prefix}}/bin",
|
||||
f"--host={triplet}",
|
||||
f"--build=x86_64-none-linux-gnu",
|
||||
"CFLAGS=-O2",
|
||||
@@ -772,9 +808,10 @@ class Releaser:
|
||||
"LDFLAGS=-Wl,-s",
|
||||
] + extra_args, cwd=build_path, env=new_env)
|
||||
with self.section_printer.group(f"Build MinGW {triplet} (autotools)"):
|
||||
self.executer.run(["make", "V=1", f"-j{self.cpu_count}"], cwd=build_path, env=new_env)
|
||||
self.executer.run(["make", f"-j{self.cpu_count}"], cwd=build_path, env=new_env)
|
||||
with self.section_printer.group(f"Install MinGW {triplet} (autotools)"):
|
||||
self.executer.run(["make", "install"], cwd=build_path, env=new_env)
|
||||
self.verify_mingw_library(triplet=ARCH_TO_TRIPLET[arch], path=install_path / "bin" / f"{self.project}.dll")
|
||||
archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time)
|
||||
|
||||
print("Recording arch-dependent extra files for MinGW development archive ...")
|
||||
@@ -830,6 +867,7 @@ class Releaser:
|
||||
self.executer.run(["cmake", "--build", str(build_path), "--verbose", "--config", build_type], cwd=build_path, env=new_env)
|
||||
with self.section_printer.group(f"Install MinGW {triplet} (CMake)"):
|
||||
self.executer.run(["cmake", "--install", str(build_path)], cwd=build_path, env=new_env)
|
||||
self.verify_mingw_library(triplet=ARCH_TO_TRIPLET[arch], path=install_path / "bin" / f"{self.project}.dll")
|
||||
archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time)
|
||||
|
||||
print("Recording arch-dependent extra files for MinGW development archive ...")
|
||||
@@ -857,22 +895,25 @@ class Releaser:
|
||||
self.artifacts["mingw-devel-tar-gz"] = tgz_path
|
||||
self.artifacts["mingw-devel-tar-xz"] = txz_path
|
||||
|
||||
def _detect_android_api(self, android_home: str) -> typing.Optional[int]:
|
||||
def _detect_android_api(self, android_home: str) -> typing.Optional[AndroidApiVersion]:
|
||||
platform_dirs = list(Path(p) for p in glob.glob(f"{android_home}/platforms/android-*"))
|
||||
re_platform = re.compile("android-([0-9]+)")
|
||||
platform_versions = []
|
||||
re_platform = re.compile("^android-([0-9]+)(?:-ext([0-9]+))?$")
|
||||
platform_versions: list[AndroidApiVersion] = []
|
||||
for platform_dir in platform_dirs:
|
||||
logger.debug("Found Android Platform SDK: %s", platform_dir)
|
||||
if not (platform_dir / "android.jar").is_file():
|
||||
logger.debug("Skipping SDK, missing android.jar")
|
||||
continue
|
||||
if m:= re_platform.match(platform_dir.name):
|
||||
platform_versions.append(int(m.group(1)))
|
||||
platform_versions.sort()
|
||||
platform_versions.append(AndroidApiVersion(name=platform_dir.name, ints=(int(m.group(1)), int(m.group(2) or 0))))
|
||||
platform_versions.sort(key=lambda v: v.ints)
|
||||
logger.info("Available platform versions: %s", platform_versions)
|
||||
platform_versions = list(filter(lambda v: v >= self._android_api_minimum, platform_versions))
|
||||
logger.info("Valid platform versions (>=%d): %s", self._android_api_minimum, platform_versions)
|
||||
platform_versions = list(filter(lambda v: v.ints >= self._android_api_minimum.ints, platform_versions))
|
||||
logger.info("Valid platform versions (>=%s): %s", self._android_api_minimum.ints, platform_versions)
|
||||
if not platform_versions:
|
||||
return None
|
||||
android_api = platform_versions[0]
|
||||
logger.info("Selected API version %d", android_api)
|
||||
logger.info("Selected API version %s", android_api)
|
||||
return android_api
|
||||
|
||||
def _get_prefab_json_text(self) -> str:
|
||||
@@ -896,8 +937,19 @@ class Releaser:
|
||||
return json.dumps(module_json_dict, indent=4)
|
||||
|
||||
@property
|
||||
def _android_api_minimum(self):
|
||||
return self.release_info["android"]["api-minimum"]
|
||||
def _android_api_minimum(self) -> AndroidApiVersion:
|
||||
value = self.release_info["android"]["api-minimum"]
|
||||
if isinstance(value, int):
|
||||
ints = (value, )
|
||||
elif isinstance(value, str):
|
||||
ints = tuple(split("."))
|
||||
else:
|
||||
raise ValueError("Invalid android.api-minimum: must be X or X.Y")
|
||||
match len(ints):
|
||||
case 1: name = f"android-{ints[0]}"
|
||||
case 2: name = f"android-{ints[0]}-ext-{ints[1]}"
|
||||
case _: raise ValueError("Invalid android.api-minimum: must be X or X.Y")
|
||||
return AndroidApiVersion(name=name, ints=ints)
|
||||
|
||||
@property
|
||||
def _android_api_target(self):
|
||||
@@ -910,7 +962,7 @@ class Releaser:
|
||||
def _get_prefab_abi_json_text(self, abi: str, cpp: bool, shared: bool) -> str:
|
||||
abi_json_dict = {
|
||||
"abi": abi,
|
||||
"api": self._android_api_minimum,
|
||||
"api": self._android_api_minimum.ints[0],
|
||||
"ndk": self._android_ndk_minimum,
|
||||
"stl": "c++_shared" if cpp else "none",
|
||||
"static": not shared,
|
||||
@@ -923,7 +975,7 @@ class Releaser:
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.libsdl.android.{self.project}" android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
<uses-sdk android:minSdkVersion="{self._android_api_minimum}"
|
||||
<uses-sdk android:minSdkVersion="{self._android_api_minimum.ints[0]}"
|
||||
android:targetSdkVersion="{self._android_api_target}" />
|
||||
</manifest>
|
||||
""")
|
||||
@@ -933,7 +985,8 @@ class Releaser:
|
||||
if not cmake_toolchain_file.exists():
|
||||
logger.error("CMake toolchain file does not exist (%s)", cmake_toolchain_file)
|
||||
raise SystemExit(1)
|
||||
aar_path = self.dist_path / f"{self.project}-{self.version}.aar"
|
||||
aar_path = self.root / "build-android" / f"{self.project}-{self.version}.aar"
|
||||
android_dist_path = self.dist_path / f"{self.project}-devel-{self.version}-android.zip"
|
||||
android_abis = self.release_info["android"]["abis"]
|
||||
java_jars_added = False
|
||||
module_data_added = False
|
||||
@@ -941,16 +994,27 @@ class Releaser:
|
||||
shutil.rmtree(android_deps_path, ignore_errors=True)
|
||||
|
||||
for dep, depinfo in self.release_info["android"].get("dependencies", {}).items():
|
||||
android_aar = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0]
|
||||
with self.section_printer.group(f"Extracting Android dependency {dep} ({android_aar.name})"):
|
||||
self.executer.run([sys.executable, str(android_aar), "-o", str(android_deps_path)])
|
||||
dep_devel_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0]
|
||||
|
||||
dep_extract_path = self.deps_path / f"extract/android/{dep}"
|
||||
shutil.rmtree(dep_extract_path, ignore_errors=True)
|
||||
dep_extract_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with self.section_printer.group(f"Extracting Android dependency {dep} ({dep_devel_zip})"):
|
||||
with zipfile.ZipFile(dep_devel_zip, "r") as zf:
|
||||
zf.extractall(dep_extract_path)
|
||||
|
||||
dep_devel_aar = dep_extract_path / glob.glob("*.aar", root_dir=dep_extract_path)[0]
|
||||
self.executer.run([sys.executable, str(dep_devel_aar), "-o", str(android_deps_path)])
|
||||
|
||||
for module_name, module_info in self.release_info["android"]["modules"].items():
|
||||
assert "type" in module_info and module_info["type"] in ("interface", "library"), f"module {module_name} must have a valid type"
|
||||
|
||||
archive_file_tree = ArchiveFileTree()
|
||||
aar_file_tree = ArchiveFileTree()
|
||||
android_devel_file_tree = ArchiveFileTree()
|
||||
|
||||
for android_abi in android_abis:
|
||||
extra_link_options = ANDROID_ABI_EXTRA_LINK_OPTIONS.get(android_abi, "")
|
||||
with self.section_printer.group(f"Building for Android {android_api} {android_abi}"):
|
||||
build_dir = self.root / "build-android" / f"{android_abi}-build"
|
||||
install_dir = self.root / "install-android" / f"{android_abi}-install"
|
||||
@@ -961,8 +1025,11 @@ class Releaser:
|
||||
"cmake",
|
||||
"-S", str(self.root),
|
||||
"-B", str(build_dir),
|
||||
f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
|
||||
f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
|
||||
# NDK 21e does not support -ffile-prefix-map
|
||||
# f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
|
||||
# f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
|
||||
f"-DCMAKE_EXE_LINKER_FLAGS={extra_link_options}",
|
||||
f"-DCMAKE_SHARED_LINKER_FLAGS={extra_link_options}",
|
||||
f"-DCMAKE_TOOLCHAIN_FILE={cmake_toolchain_file}",
|
||||
f"-DCMAKE_PREFIX_PATH={str(android_deps_path)}",
|
||||
f"-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH",
|
||||
@@ -999,20 +1066,20 @@ class Releaser:
|
||||
assert library.suffix in (".so", ".a")
|
||||
assert library.is_file(), f"CMake should have built library '{library}' for module {module_name}"
|
||||
arcdir_prefab_libs = f"{arcdir_prefab_module}/libs/android.{android_abi}"
|
||||
archive_file_tree.add_file(NodeInArchive.from_fs(arcpath=f"{arcdir_prefab_libs}/{library.name}", path=library, time=self.arc_time))
|
||||
archive_file_tree.add_file(NodeInArchive.from_text(arcpath=f"{arcdir_prefab_libs}/abi.json", text=self._get_prefab_abi_json_text(abi=android_abi, cpp=False, shared=library.suffix == ".so"), time=self.arc_time))
|
||||
aar_file_tree.add_file(NodeInArchive.from_fs(arcpath=f"{arcdir_prefab_libs}/{library.name}", path=library, time=self.arc_time))
|
||||
aar_file_tree.add_file(NodeInArchive.from_text(arcpath=f"{arcdir_prefab_libs}/abi.json", text=self._get_prefab_abi_json_text(abi=android_abi, cpp=False, shared=library.suffix == ".so"), time=self.arc_time))
|
||||
|
||||
if not module_data_added:
|
||||
library_name = None
|
||||
if module_info["type"] == "library":
|
||||
library_name = Path(module_info["library"]).stem.removeprefix("lib")
|
||||
export_libraries = module_info.get("export-libraries", [])
|
||||
archive_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_module, "module.json"), text=self._get_prefab_module_json_text(library_name=library_name, export_libraries=export_libraries), time=self.arc_time))
|
||||
aar_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_module, "module.json"), text=self._get_prefab_module_json_text(library_name=library_name, export_libraries=export_libraries), time=self.arc_time))
|
||||
arcdir_prefab_include = f"prefab/modules/{module_name}/include"
|
||||
if "includes" in module_info:
|
||||
archive_file_tree.add_file_mapping(arc_dir=arcdir_prefab_include, file_mapping=module_info["includes"], file_mapping_root=install_dir, context=self.get_context(), time=self.arc_time)
|
||||
aar_file_tree.add_file_mapping(arc_dir=arcdir_prefab_include, file_mapping=module_info["includes"], file_mapping_root=install_dir, context=self.get_context(), time=self.arc_time)
|
||||
else:
|
||||
archive_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_include, ".keep"), text="\n", time=self.arc_time))
|
||||
aar_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_include, ".keep"), text="\n", time=self.arc_time))
|
||||
module_data_added = True
|
||||
|
||||
if not java_jars_added:
|
||||
@@ -1025,21 +1092,28 @@ class Releaser:
|
||||
assert sources_jar_path.is_file(), f"CMake should have archived the java sources into a JAR ({sources_jar_path})"
|
||||
assert doc_jar_path.is_file(), f"CMake should have archived javadoc into a JAR ({doc_jar_path})"
|
||||
|
||||
archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes.jar", path=classes_jar_path, time=self.arc_time))
|
||||
archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-sources.jar", path=sources_jar_path, time=self.arc_time))
|
||||
archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-doc.jar", path=doc_jar_path, time=self.arc_time))
|
||||
aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes.jar", path=classes_jar_path, time=self.arc_time))
|
||||
aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-sources.jar", path=sources_jar_path, time=self.arc_time))
|
||||
aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-doc.jar", path=doc_jar_path, time=self.arc_time))
|
||||
|
||||
assert ("jars" in self.release_info["android"] and java_jars_added) or "jars" not in self.release_info["android"], "Must have archived java JAR archives"
|
||||
|
||||
archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=self.arc_time)
|
||||
aar_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"]["aar-files"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time)
|
||||
|
||||
archive_file_tree.add_file(NodeInArchive.from_text(arcpath="prefab/prefab.json", text=self._get_prefab_json_text(), time=self.arc_time))
|
||||
archive_file_tree.add_file(NodeInArchive.from_text(arcpath="AndroidManifest.xml", text=self._get_android_manifest_text(), time=self.arc_time))
|
||||
aar_file_tree.add_file(NodeInArchive.from_text(arcpath="prefab/prefab.json", text=self._get_prefab_json_text(), time=self.arc_time))
|
||||
aar_file_tree.add_file(NodeInArchive.from_text(arcpath="AndroidManifest.xml", text=self._get_android_manifest_text(), time=self.arc_time))
|
||||
|
||||
with Archiver(zip_path=aar_path) as archiver:
|
||||
archive_file_tree.add_to_archiver(archive_base="", archiver=archiver)
|
||||
aar_file_tree.add_to_archiver(archive_base="", archiver=archiver)
|
||||
archiver.add_git_hash(arcdir="", commit=self.commit, time=self.arc_time)
|
||||
self.artifacts[f"android-aar"] = aar_path
|
||||
|
||||
android_devel_file_tree.add_file(NodeInArchive.from_fs(arcpath=aar_path.name, path=aar_path))
|
||||
android_devel_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"]["files"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time)
|
||||
with Archiver(zip_path=android_dist_path) as archiver:
|
||||
android_devel_file_tree.add_to_archiver(archive_base="", archiver=archiver)
|
||||
archiver.add_git_hash(arcdir="", commit=self.commit, time=self.arc_time)
|
||||
|
||||
self.artifacts[f"android-aar"] = android_dist_path
|
||||
|
||||
def download_dependencies(self):
|
||||
shutil.rmtree(self.deps_path, ignore_errors=True)
|
||||
@@ -1076,7 +1150,7 @@ class Releaser:
|
||||
assert len(msvc_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {msvc_matches}"
|
||||
if "android" in self.release_info:
|
||||
android_matches = glob.glob(self.release_info["android"]["dependencies"][dep]["artifact"], root_dir=self.deps_path)
|
||||
assert len(android_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {msvc_matches}"
|
||||
assert len(android_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {android_matches}"
|
||||
|
||||
@staticmethod
|
||||
def _arch_to_vs_platform(arch: str, configuration: str="Release") -> VsArchPlatformConfig:
|
||||
@@ -1202,6 +1276,10 @@ class Releaser:
|
||||
platform_context = self.get_context(extra_context=arch_platform.extra_context())
|
||||
|
||||
build_type = "Release"
|
||||
extra_context = {
|
||||
"ARCH": arch_platform.arch,
|
||||
"PLATFORM": arch_platform.platform,
|
||||
}
|
||||
|
||||
built_paths = set(install_path / configure_text(f, context=platform_context) for file_mapping in (self.release_info["msvc"]["cmake"]["files-lib"], self.release_info["msvc"]["cmake"]["files-devel"]) for files_list in file_mapping.values() for f in files_list)
|
||||
logger.info("CMake builds these files, to be included in the package: %s", built_paths)
|
||||
@@ -1252,7 +1330,7 @@ class Releaser:
|
||||
logger.info("Collecting files...")
|
||||
archive_file_tree = ArchiveFileTree()
|
||||
archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["cmake"]["files-lib"], file_mapping_root=install_path, context=platform_context, time=self.arc_time)
|
||||
archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["files-lib"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time)
|
||||
archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["files-lib"], file_mapping_root=self.root, context=self.get_context(extra_context=extra_context), time=self.arc_time)
|
||||
|
||||
logger.info("Creating %s", zip_path)
|
||||
with Archiver(zip_path=zip_path) as archiver:
|
||||
@@ -1316,7 +1394,7 @@ def main(argv=None) -> int:
|
||||
parser.add_argument("--actions", choices=["download", "source", "android", "mingw", "msvc", "dmg"], required=True, nargs="+", dest="actions", help="What to do?")
|
||||
parser.set_defaults(loglevel=logging.INFO)
|
||||
parser.add_argument('--vs-year', dest="vs_year", help="Visual Studio year")
|
||||
parser.add_argument('--android-api', type=int, dest="android_api", help="Android API version")
|
||||
parser.add_argument('--android-api', dest="android_api", help="Android API version")
|
||||
parser.add_argument('--android-home', dest="android_home", default=os.environ.get("ANDROID_HOME"), help="Android Home folder")
|
||||
parser.add_argument('--android-ndk-home', dest="android_ndk_home", default=os.environ.get("ANDROID_NDK_HOME"), help="Android NDK Home folder")
|
||||
parser.add_argument('--cmake-generator', dest="cmake_generator", default="Ninja", help="CMake Generator")
|
||||
@@ -1443,14 +1521,27 @@ def main(argv=None) -> int:
|
||||
if args.android_api is None:
|
||||
with section_printer.group("Detect Android APIS"):
|
||||
args.android_api = releaser._detect_android_api(android_home=args.android_home)
|
||||
if args.android_api is None or not (Path(args.android_home) / f"platforms/android-{args.android_api}").is_dir():
|
||||
else:
|
||||
try:
|
||||
android_api_ints = tuple(int(v) for v in args.android_api.split("."))
|
||||
match len(android_api_ints):
|
||||
case 1: android_api_name = f"android-{android_api_ints[0]}"
|
||||
case 2: android_api_name = f"android-{android_api_ints[0]}-ext-{android_api_ints[1]}"
|
||||
case _: raise ValueError
|
||||
except ValueError:
|
||||
logger.error("Invalid --android-api, must be a 'X' or 'X.Y' version")
|
||||
args.android_api = AndroidApiVersion(ints=android_api_ints, name=android_api_name)
|
||||
if args.android_api is None:
|
||||
parser.error("Invalid --android-api, and/or could not be detected")
|
||||
android_api_path = Path(args.android_home) / f"platforms/{args.android_api.name}"
|
||||
if not android_api_path.is_dir():
|
||||
logger.warning(f"Android API directory does not exist ({android_api_path})")
|
||||
with section_printer.group("Android arguments"):
|
||||
print(f"android_home = {args.android_home}")
|
||||
print(f"android_ndk_home = {args.android_ndk_home}")
|
||||
print(f"android_api = {args.android_api}")
|
||||
releaser.create_android_archives(
|
||||
android_api=args.android_api,
|
||||
android_api=args.android_api.ints[0],
|
||||
android_home=args.android_home,
|
||||
android_ndk_home=args.android_ndk_home,
|
||||
)
|
||||
|
||||
@@ -3515,8 +3515,8 @@ orig_CFLAGS="$CFLAGS"
|
||||
|
||||
# See docs/release_checklist.md
|
||||
SDL_MAJOR_VERSION=2
|
||||
SDL_MINOR_VERSION=32
|
||||
SDL_MICRO_VERSION=10
|
||||
SDL_MINOR_VERSION=33
|
||||
SDL_MICRO_VERSION=0
|
||||
SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
|
||||
|
||||
SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION`
|
||||
|
||||
+2
-2
@@ -12,8 +12,8 @@ orig_CFLAGS="$CFLAGS"
|
||||
dnl Set various version strings - taken gratefully from the GTk sources
|
||||
# See docs/release_checklist.md
|
||||
SDL_MAJOR_VERSION=2
|
||||
SDL_MINOR_VERSION=32
|
||||
SDL_MICRO_VERSION=10
|
||||
SDL_MINOR_VERSION=33
|
||||
SDL_MICRO_VERSION=0
|
||||
SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
|
||||
|
||||
SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION`
|
||||
|
||||
+5
-1
@@ -11,7 +11,7 @@ Credit to
|
||||
## Building
|
||||
To build SDL2 library for the PS2, make sure you have the latest PS2Dev status and run:
|
||||
```bash
|
||||
cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=$PS2DEV/ps2sdk/ps2dev.cmake
|
||||
cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=$PS2DEV/share/ps2dev.cmake
|
||||
cmake --build build
|
||||
cmake --install build
|
||||
```
|
||||
@@ -19,6 +19,10 @@ cmake --install build
|
||||
## Hints
|
||||
The PS2 port has a special Hint for having a dynamic VSYNC. The Hint is `SDL_HINT_PS2_DYNAMIC_VSYNC`.
|
||||
If you enabled the dynamic vsync having as well `SDL_RENDERER_PRESENTVSYNC` enabled, then if the app is not able to run at 60 FPS, automatically the `vsync` will be disabled having a better performance, instead of droping FPS to 30.
|
||||
- `SDL_HINT_PS2_GS_WIDTH`: Width of the framebuffer. Defaults to 640.
|
||||
- `SDL_HINT_PS2_GS_HEIGHT`: Height of the framebuffer. Defaults to 448.
|
||||
- `SDL_HINT_PS2_GS_PROGRESSIVE`: Whether to use progressive, instead of interlaced. Defaults to 0.
|
||||
- `SDL_HINT_PS2_GS_MODE`: Regional standard of the signal. "NTSC" (60hz), "PAL" (50hz) or "" (the console's region, default).
|
||||
|
||||
## Notes
|
||||
If you trying to debug a SDL app through [ps2client](https://github.com/ps2dev/ps2client) you need to avoid the IOP reset, otherwise you will lose the conection with your computer.
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ cmake --install build
|
||||
|
||||
|
||||
## Compiling a HelloWorld
|
||||
[PSP Hello World](https://psp-dev.org/doku.php?id=tutorial:hello_world)
|
||||
[PSP Hello World](https://pspdev.github.io/basic_programs.html#hello-world)
|
||||
|
||||
## To Do
|
||||
- PSP Screen Keyboard
|
||||
|
||||
@@ -14,7 +14,6 @@ Works out of box.
|
||||
Windows:
|
||||
Unfortunately there is no windows support as of yet. Support for Windows 7 is planned, but we currently have no way to test. If you have a Windows 7 WM_TOUCH supported device, and are willing to help test please contact me at jim.tla+sdl_touch@gmail.com
|
||||
|
||||
===========================================================================
|
||||
Events
|
||||
===========================================================================
|
||||
SDL_FINGERDOWN:
|
||||
@@ -39,7 +38,6 @@ Fields:
|
||||
Same as SDL_FINGERDOWN.
|
||||
|
||||
|
||||
===========================================================================
|
||||
Functions
|
||||
===========================================================================
|
||||
SDL provides the ability to access the underlying SDL_Finger structures.
|
||||
@@ -76,7 +74,6 @@ A SDL_Finger has the following fields:
|
||||
The pressure of the touch.
|
||||
|
||||
|
||||
===========================================================================
|
||||
Notes
|
||||
===========================================================================
|
||||
For a complete example see test/testgesture.c
|
||||
|
||||
+11
-1
@@ -648,7 +648,7 @@ extern DECLSPEC int SDLCALL SDL_GetDefaultAudioInfo(char **name,
|
||||
* \param obtained an SDL_AudioSpec structure filled in with the actual output
|
||||
* format; see SDL_OpenAudio() for more information.
|
||||
* \param allowed_changes 0, or one or more flags OR'd together.
|
||||
* \returns a valid device ID that is > 0 on success or 0 on failure; call
|
||||
* \returns a valid device ID > 0 on success or 0 on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* For compatibility with SDL 1.2, this will never return 1, since
|
||||
@@ -1059,6 +1059,9 @@ extern DECLSPEC int SDLCALL SDL_AudioStreamGet(SDL_AudioStream *stream, void *bu
|
||||
* resample correctly, so this number might be lower than what you expect, or
|
||||
* even be zero. Add more data or flush the stream if you need the data now.
|
||||
*
|
||||
* \param stream the audio stream to query.
|
||||
* \returns the number of bytes available.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.7.
|
||||
*
|
||||
* \sa SDL_NewAudioStream
|
||||
@@ -1078,6 +1081,9 @@ extern DECLSPEC int SDLCALL SDL_AudioStreamAvailable(SDL_AudioStream *stream);
|
||||
* audio gaps in the output. Generally this is intended to signal the end of
|
||||
* input, so the complete output becomes available.
|
||||
*
|
||||
* \param stream the audio stream to flush.
|
||||
* \returns 0 on success, otherwise -1.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.7.
|
||||
*
|
||||
* \sa SDL_NewAudioStream
|
||||
@@ -1092,6 +1098,8 @@ extern DECLSPEC int SDLCALL SDL_AudioStreamFlush(SDL_AudioStream *stream);
|
||||
/**
|
||||
* Clear any pending data in the stream without converting it
|
||||
*
|
||||
* \param stream the audio stream to clear.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.7.
|
||||
*
|
||||
* \sa SDL_NewAudioStream
|
||||
@@ -1106,6 +1114,8 @@ extern DECLSPEC void SDLCALL SDL_AudioStreamClear(SDL_AudioStream *stream);
|
||||
/**
|
||||
* Free an audio stream
|
||||
*
|
||||
* \param stream the audio stream to free.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.7.
|
||||
*
|
||||
* \sa SDL_NewAudioStream
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version,
|
||||
so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */
|
||||
#ifdef __clang__
|
||||
#if defined(__clang__) && !_SDL_HAS_BUILTIN(_m_prefetch)
|
||||
#ifndef __PRFCHWINTRIN_H
|
||||
#define __PRFCHWINTRIN_H
|
||||
static __inline__ void __attribute__((__always_inline__, __nodebug__))
|
||||
|
||||
@@ -226,6 +226,7 @@ extern DECLSPEC int SDLCALL SDL_GameControllerNumMappings(void);
|
||||
/**
|
||||
* Get the mapping at a particular index.
|
||||
*
|
||||
* \param mapping_index mapping index.
|
||||
* \returns the mapping string. Must be freed with SDL_free(). Returns NULL if
|
||||
* the index is out of range.
|
||||
*
|
||||
@@ -850,6 +851,9 @@ extern DECLSPEC Uint8 SDLCALL SDL_GameControllerGetButton(SDL_GameController *ga
|
||||
/**
|
||||
* Get the number of touchpads on a game controller.
|
||||
*
|
||||
* \param gamecontroller a controller.
|
||||
* \returns number of touchpads.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.14.
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpads(SDL_GameController *gamecontroller);
|
||||
@@ -858,6 +862,10 @@ extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpads(SDL_GameController
|
||||
* Get the number of supported simultaneous fingers on a touchpad on a game
|
||||
* controller.
|
||||
*
|
||||
* \param gamecontroller a controller.
|
||||
* \param touchpad a touchpad.
|
||||
* \returns number of supported simultaneous fingers.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.14.
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpadFingers(SDL_GameController *gamecontroller, int touchpad);
|
||||
@@ -865,6 +873,15 @@ extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpadFingers(SDL_GameCont
|
||||
/**
|
||||
* Get the current state of a finger on a touchpad on a game controller.
|
||||
*
|
||||
* \param gamecontroller a controller.
|
||||
* \param touchpad a touchpad.
|
||||
* \param finger a finger.
|
||||
* \param state a pointer filled with the finger state.
|
||||
* \param x a pointer filled with the x position.
|
||||
* \param y a pointer filled with the y position.
|
||||
* \param pressure a pointer filled with pressure value.
|
||||
* \returns 0 on success or negative on failure.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.14.
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_GameControllerGetTouchpadFinger(SDL_GameController *gamecontroller, int touchpad, int finger, Uint8 *state, float *x, float *y, float *pressure);
|
||||
|
||||
@@ -227,6 +227,7 @@ extern DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open(unsigned short vendor_id,
|
||||
* platform-specific path name can be used (eg: /dev/hidraw0 on Linux).
|
||||
*
|
||||
* \param path The path name of the device to open.
|
||||
* \param bExclusive boolean exclusive.
|
||||
* \returns a pointer to a SDL_hid_device object on success or NULL on
|
||||
* failure.
|
||||
*
|
||||
|
||||
+33
-2
@@ -1262,8 +1262,8 @@ extern "C" {
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
*
|
||||
* - "0": RAWINPUT drivers are not used
|
||||
* - "1": RAWINPUT drivers are used (the default)
|
||||
* - "0": RAWINPUT drivers are not used (the default)
|
||||
* - "1": RAWINPUT drivers are used
|
||||
*/
|
||||
#define SDL_HINT_JOYSTICK_RAWINPUT "SDL_JOYSTICK_RAWINPUT"
|
||||
|
||||
@@ -2024,6 +2024,37 @@ extern "C" {
|
||||
*/
|
||||
#define SDL_HINT_ROG_GAMEPAD_MICE_EXCLUDED "SDL_ROG_GAMEPAD_MICE_EXCLUDED"
|
||||
|
||||
/**
|
||||
* Variable controlling the width of the PS2's framebuffer in pixels
|
||||
*
|
||||
* By default, this variable is "640"
|
||||
*/
|
||||
#define SDL_HINT_PS2_GS_WIDTH "SDL_PS2_GS_WIDTH"
|
||||
|
||||
/**
|
||||
* Variable controlling the height of the PS2's framebuffer in pixels
|
||||
*
|
||||
* By default, this variable is "448"
|
||||
*/
|
||||
#define SDL_HINT_PS2_GS_HEIGHT "SDL_PS2_GS_HEIGHT"
|
||||
|
||||
/**
|
||||
* Variable controlling whether the signal is interlaced or progressive
|
||||
*
|
||||
* - "0": Image is interlaced. (default)
|
||||
* - "1": Image is progressive
|
||||
*/
|
||||
#define SDL_HINT_PS2_GS_PROGRESSIVE "SDL_PS2_GS_PROGRESSIVE"
|
||||
|
||||
/**
|
||||
* Variable controlling the video mode of the console
|
||||
*
|
||||
* - "": Console-native. (default)
|
||||
* - "NTSC": 60hz region
|
||||
* - "PAL": 50hz region
|
||||
*/
|
||||
#define SDL_HINT_PS2_GS_MODE "SDL_PS2_GS_MODE"
|
||||
|
||||
/**
|
||||
* A variable controlling if VSYNC is automatically disable if doesn't reach
|
||||
* the enough FPS
|
||||
|
||||
@@ -214,6 +214,9 @@ extern DECLSPEC const char *SDLCALL SDL_JoystickPathForIndex(int device_index);
|
||||
* Get the player index of a joystick, or -1 if it's not available This can be
|
||||
* called before any joysticks are opened.
|
||||
*
|
||||
* \param device_index device index.
|
||||
* \returns player index, or -1 if not available.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.9.
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_JoystickGetDevicePlayerIndex(int device_index);
|
||||
@@ -356,6 +359,10 @@ extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromPlayerIndex(int player_ind
|
||||
/**
|
||||
* Attach a new virtual joystick.
|
||||
*
|
||||
* \param type joystick type.
|
||||
* \param naxes number of axes.
|
||||
* \param nbuttons number of buttons.
|
||||
* \param nhats number of hats.
|
||||
* \returns the joystick's device index, or -1 if an error occurred.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.14.
|
||||
@@ -409,6 +416,7 @@ typedef struct SDL_VirtualJoystickDesc
|
||||
/**
|
||||
* Attach a new virtual joystick with extended properties.
|
||||
*
|
||||
* \param desc joystick description.
|
||||
* \returns the joystick's device index, or -1 if an error occurred.
|
||||
*
|
||||
* \since This function is available since SDL 2.24.0.
|
||||
|
||||
@@ -298,6 +298,9 @@ extern DECLSPEC void SDLCALL SDL_ClearComposition(void);
|
||||
/**
|
||||
* Returns if an IME Composite or Candidate window is currently shown.
|
||||
*
|
||||
* \returns SDL_TRUE if an IME Composite or Candidate window is currently
|
||||
* shown else SDL_FALSE.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.22.
|
||||
*/
|
||||
extern DECLSPEC SDL_bool SDLCALL SDL_IsTextInputShown(void);
|
||||
|
||||
@@ -41,12 +41,18 @@
|
||||
*
|
||||
* A special exception is the number keys at the top of the keyboard which map
|
||||
* to SDLK_0...SDLK_9 on AZERTY layouts.
|
||||
*
|
||||
* The actual values that might be set for this type are listed in the
|
||||
* SDL_KeyCode (capital C) enumeration.
|
||||
*/
|
||||
typedef Sint32 SDL_Keycode;
|
||||
|
||||
#define SDLK_SCANCODE_MASK (1<<30)
|
||||
#define SDL_SCANCODE_TO_KEYCODE(X) (X | SDLK_SCANCODE_MASK)
|
||||
|
||||
/**
|
||||
* The possible values for keycodes.
|
||||
*/
|
||||
typedef enum SDL_KeyCode
|
||||
{
|
||||
SDLK_UNKNOWN = 0,
|
||||
|
||||
+1
-2
@@ -163,8 +163,7 @@ extern DECLSPEC void SDLCALL SDL_LogResetPriorities(void);
|
||||
/**
|
||||
* Log a message with SDL_LOG_CATEGORY_APPLICATION and SDL_LOG_PRIORITY_INFO.
|
||||
*
|
||||
* = * \param fmt a printf() style message format string
|
||||
*
|
||||
* \param fmt a printf() style message format string.
|
||||
* \param ... additional parameters matching % tokens in the `fmt` string, if
|
||||
* any.
|
||||
*
|
||||
|
||||
+2
-2
@@ -187,8 +187,8 @@ extern DECLSPEC void SDLCALL SDL_SetMainReady(void);
|
||||
* \param name the window class name, in UTF-8 encoding. If NULL, SDL
|
||||
* currently uses "SDL_app" but this isn't guaranteed.
|
||||
* \param style the value to use in WNDCLASSEX::style. If `name` is NULL, SDL
|
||||
* currently uses `(CS_BYTEALIGNCLIENT | CS_OWNDC)` regardless of
|
||||
* what is specified here.
|
||||
* currently uses `(CS_BYTEALIGNCLIENT \| CS_OWNDC)` regardless
|
||||
* of what is specified here.
|
||||
* \param hInst the HINSTANCE to use in WNDCLASSEX::hInstance. If zero, SDL
|
||||
* will use `GetModuleHandle(NULL)` instead.
|
||||
* \returns 0 on success, -1 on error. SDL_GetError() may have details.
|
||||
|
||||
@@ -59,6 +59,9 @@ typedef void *SDL_MetalView;
|
||||
* The returned handle can be casted directly to a NSView or UIView. To access
|
||||
* the backing CAMetalLayer, call SDL_Metal_GetLayer().
|
||||
*
|
||||
* \param window the window.
|
||||
* \returns handle NSView or UIView.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.12.
|
||||
*
|
||||
* \sa SDL_Metal_DestroyView
|
||||
@@ -72,6 +75,8 @@ extern DECLSPEC SDL_MetalView SDLCALL SDL_Metal_CreateView(SDL_Window * window);
|
||||
* This should be called before SDL_DestroyWindow, if SDL_Metal_CreateView was
|
||||
* called after SDL_CreateWindow.
|
||||
*
|
||||
* \param view the SDL_MetalView object.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.12.
|
||||
*
|
||||
* \sa SDL_Metal_CreateView
|
||||
@@ -81,6 +86,9 @@ extern DECLSPEC void SDLCALL SDL_Metal_DestroyView(SDL_MetalView view);
|
||||
/**
|
||||
* Get a pointer to the backing CAMetalLayer for the given view.
|
||||
*
|
||||
* \param view the SDL_MetalView object.
|
||||
* \returns a pointer.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.14.
|
||||
*
|
||||
* \sa SDL_Metal_CreateView
|
||||
|
||||
@@ -106,6 +106,10 @@ typedef struct SDL_FRect
|
||||
|
||||
/**
|
||||
* Returns true if point resides inside a rectangle.
|
||||
*
|
||||
* \param p the point to test.
|
||||
* \param r the rectangle to test.
|
||||
* \returns SDL_TRUE if `p` is contained by `r`, SDL_FALSE otherwise.
|
||||
*/
|
||||
SDL_FORCE_INLINE SDL_bool SDL_PointInRect(const SDL_Point *p, const SDL_Rect *r)
|
||||
{
|
||||
@@ -115,6 +119,9 @@ SDL_FORCE_INLINE SDL_bool SDL_PointInRect(const SDL_Point *p, const SDL_Rect *r)
|
||||
|
||||
/**
|
||||
* Returns true if the rectangle has no area.
|
||||
*
|
||||
* \param r the rectangle to test.
|
||||
* \returns SDL_TRUE if the rectangle is "empty", SDL_FALSE otherwise.
|
||||
*/
|
||||
SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r)
|
||||
{
|
||||
@@ -123,6 +130,10 @@ SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r)
|
||||
|
||||
/**
|
||||
* Returns true if the two rectangles are equal.
|
||||
*
|
||||
* \param a the first rectangle to test.
|
||||
* \param b the second rectangle to test.
|
||||
* \returns SDL_TRUE if the rectangles are equal, SDL_FALSE otherwise.
|
||||
*/
|
||||
SDL_FORCE_INLINE SDL_bool SDL_RectEquals(const SDL_Rect *a, const SDL_Rect *b)
|
||||
{
|
||||
@@ -229,6 +240,10 @@ extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRectAndLine(const SDL_Rect *
|
||||
|
||||
/**
|
||||
* Returns true if point resides inside a rectangle.
|
||||
*
|
||||
* \param p the point to test.
|
||||
* \param r the rectangle to test.
|
||||
* \returns SDL_TRUE if `p` is contained by `r`, SDL_FALSE otherwise.
|
||||
*/
|
||||
SDL_FORCE_INLINE SDL_bool SDL_PointInFRect(const SDL_FPoint *p, const SDL_FRect *r)
|
||||
{
|
||||
@@ -238,6 +253,9 @@ SDL_FORCE_INLINE SDL_bool SDL_PointInFRect(const SDL_FPoint *p, const SDL_FRect
|
||||
|
||||
/**
|
||||
* Returns true if the rectangle has no area.
|
||||
*
|
||||
* \param r the rectangle to test.
|
||||
* \returns SDL_TRUE if the rectangle is "empty", SDL_FALSE otherwise.
|
||||
*/
|
||||
SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r)
|
||||
{
|
||||
@@ -247,6 +265,11 @@ SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r)
|
||||
/**
|
||||
* Returns true if the two rectangles are equal, within some given epsilon.
|
||||
*
|
||||
* \param a the first rectangle to test.
|
||||
* \param b the second rectangle to test.
|
||||
* \param epsilon the epsilon value for comparison.
|
||||
* \returns SDL_TRUE if the rectangles are equal, SDL_FALSE otherwise.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.22.
|
||||
*/
|
||||
SDL_FORCE_INLINE SDL_bool SDL_FRectEqualsEpsilon(const SDL_FRect *a, const SDL_FRect *b, const float epsilon)
|
||||
@@ -262,6 +285,10 @@ SDL_FORCE_INLINE SDL_bool SDL_FRectEqualsEpsilon(const SDL_FRect *a, const SDL_F
|
||||
/**
|
||||
* Returns true if the two rectangles are equal, using a default epsilon.
|
||||
*
|
||||
* \param a the first rectangle to test.
|
||||
* \param b the second rectangle to test.
|
||||
* \returns SDL_TRUE if the rectangles are equal, SDL_FALSE otherwise.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.22.
|
||||
*/
|
||||
SDL_FORCE_INLINE SDL_bool SDL_FRectEquals(const SDL_FRect *a, const SDL_FRect *b)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
* - single pixel lines
|
||||
* - filled rectangles
|
||||
* - texture images
|
||||
* - 2D polygons
|
||||
*
|
||||
* The primitives may be drawn in opaque, blended, or additive modes.
|
||||
*
|
||||
@@ -38,7 +39,7 @@
|
||||
* may also be stretched with linear interpolation.
|
||||
*
|
||||
* This API is designed to accelerate simple 2D operations. You may want more
|
||||
* functionality such as polygons and particle effects and in that case you
|
||||
* functionality such as 3D polygons and particle effects and in that case you
|
||||
* should use SDL's OpenGL/Direct3D support or one of the many good 3D
|
||||
* engines.
|
||||
*
|
||||
|
||||
@@ -467,6 +467,11 @@ typedef void (SDLCALL *SDL_free_func)(void *mem);
|
||||
/**
|
||||
* Get the original set of SDL memory functions
|
||||
*
|
||||
* \param malloc_func filled with malloc function.
|
||||
* \param calloc_func filled with calloc function.
|
||||
* \param realloc_func filled with realloc function.
|
||||
* \param free_func filled with free function.
|
||||
*
|
||||
* \since This function is available since SDL 2.24.0.
|
||||
*/
|
||||
extern DECLSPEC void SDLCALL SDL_GetOriginalMemoryFunctions(SDL_malloc_func *malloc_func,
|
||||
@@ -477,6 +482,11 @@ extern DECLSPEC void SDLCALL SDL_GetOriginalMemoryFunctions(SDL_malloc_func *mal
|
||||
/**
|
||||
* Get the current set of SDL memory functions
|
||||
*
|
||||
* \param malloc_func filled with malloc function.
|
||||
* \param calloc_func filled with calloc function.
|
||||
* \param realloc_func filled with realloc function.
|
||||
* \param free_func filled with free function.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.7.
|
||||
*/
|
||||
extern DECLSPEC void SDLCALL SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func,
|
||||
@@ -487,6 +497,13 @@ extern DECLSPEC void SDLCALL SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func
|
||||
/**
|
||||
* Replace SDL's memory allocation functions with a custom set
|
||||
*
|
||||
* \param malloc_func custom malloc function.
|
||||
* \param calloc_func custom calloc function.
|
||||
* \param realloc_func custom realloc function.
|
||||
* \param free_func custom free function.
|
||||
* \returns 0 on success or -1 on failure; call SDL_GetError() for more
|
||||
* information.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.7.
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_SetMemoryFunctions(SDL_malloc_func malloc_func,
|
||||
@@ -497,6 +514,8 @@ extern DECLSPEC int SDLCALL SDL_SetMemoryFunctions(SDL_malloc_func malloc_func,
|
||||
/**
|
||||
* Get the number of outstanding (unfreed) allocations
|
||||
*
|
||||
* \returns number of unfreed allocations.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.7.
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_GetNumAllocations(void);
|
||||
@@ -565,6 +584,7 @@ SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords)
|
||||
return;
|
||||
}
|
||||
switch (dwords % 4) {
|
||||
default:
|
||||
case 0: do { *_p++ = _val; SDL_FALLTHROUGH;
|
||||
case 3: *_p++ = _val; SDL_FALLTHROUGH;
|
||||
case 2: *_p++ = _val; SDL_FALLTHROUGH;
|
||||
@@ -715,6 +735,12 @@ extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf,
|
||||
* This function converts a buffer or string between encodings in one pass,
|
||||
* returning a string that must be freed with SDL_free() or NULL on error.
|
||||
*
|
||||
* \param tocode the character encoding of the output string.
|
||||
* \param fromcode the character encoding of data in `inbuf`.
|
||||
* \param inbuf the string to convert to a different encoding.
|
||||
* \param inbytesleft the size of the input string _in bytes_.
|
||||
* \returns a new string, converted to the new encoding, or NULL on error.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.0.
|
||||
*/
|
||||
extern DECLSPEC char *SDLCALL SDL_iconv_string(const char *tocode,
|
||||
@@ -806,6 +832,11 @@ SDL_FORCE_INLINE void *SDL_memcpy4(SDL_OUT_BYTECAP(dwords*4) void *dst, SDL_IN_B
|
||||
*
|
||||
* Otherwise store a * b via ret and return 0.
|
||||
*
|
||||
* \param a the multiplicand.
|
||||
* \param b the multiplier.
|
||||
* \param ret on non-overflow output, stores the multiplication result.
|
||||
* \returns -1 on overflow, 0 if result is multiplied without overflow.
|
||||
*
|
||||
* \since This function is available since SDL 2.24.0.
|
||||
*/
|
||||
SDL_FORCE_INLINE int SDL_size_mul_overflow (size_t a,
|
||||
@@ -837,6 +868,11 @@ SDL_FORCE_INLINE int _SDL_size_mul_overflow_builtin (size_t a,
|
||||
*
|
||||
* Otherwise store a + b via ret and return 0.
|
||||
*
|
||||
* \param a the first addend.
|
||||
* \param b the second addend.
|
||||
* \param ret on non-overflow output, stores the addition result.
|
||||
* \returns false on overflow, true if result is added without overflow.
|
||||
*
|
||||
* \since This function is available since SDL 2.24.0.
|
||||
*/
|
||||
SDL_FORCE_INLINE int SDL_size_add_overflow (size_t a,
|
||||
|
||||
+58
-6
@@ -801,15 +801,14 @@ extern DECLSPEC int SDLCALL SDL_FillRect
|
||||
extern DECLSPEC int SDLCALL SDL_FillRects
|
||||
(SDL_Surface * dst, const SDL_Rect * rects, int count, Uint32 color);
|
||||
|
||||
/* !!! FIXME: merge this documentation with the wiki */
|
||||
|
||||
/**
|
||||
* Performs a fast blit from the source surface to the destination surface.
|
||||
*
|
||||
* This assumes that the source and destination rectangles are the same size.
|
||||
* If either `srcrect` or `dstrect` are NULL, the entire surface (`src` or
|
||||
* `dst`) is copied. The final blit rectangle is saved in `dstrect` after
|
||||
* all clipping is performed.
|
||||
* `dstrect`'s width and height are ignored, only its position is used. If
|
||||
* either `srcrect` or `dstrect` are NULL, the entire surface (`src` or `dst`)
|
||||
* is copied. The final blit rectangle is saved in `dstrect` after all
|
||||
* clipping is performed.
|
||||
*
|
||||
* The blit function should not be called on a locked surface.
|
||||
*
|
||||
@@ -859,7 +858,17 @@ extern DECLSPEC int SDLCALL SDL_FillRects
|
||||
* You should call SDL_BlitSurface() unless you know exactly how SDL blitting
|
||||
* works internally and how to use the other blit functions.
|
||||
*
|
||||
* \returns 0 if the blit is successful, otherwise it returns -1.
|
||||
* \param src the SDL_Surface structure to be copied from.
|
||||
* \param srcrect the SDL_Rect structure representing the rectangle to be
|
||||
* copied, or NULL to copy the entire surface.
|
||||
* \param dst the SDL_Surface structure that is the blit target.
|
||||
* \param dstrect the SDL_Rect structure representing the x and y position in
|
||||
* the destination surface, or NULL for (0,0). The width and
|
||||
* height are ignored, and are copied from `srcrect`. If you
|
||||
* want a specific width and height, you should use
|
||||
* SDL_BlitScaled().
|
||||
* \returns 0 if the blit is successful or a negative error code on failure;
|
||||
* call SDL_GetError() for more information.
|
||||
*/
|
||||
#define SDL_BlitSurface SDL_UpperBlit
|
||||
|
||||
@@ -869,6 +878,18 @@ extern DECLSPEC int SDLCALL SDL_FillRects
|
||||
* SDL_UpperBlit() has been replaced by SDL_BlitSurface(), which is merely a
|
||||
* macro for this function with a less confusing name.
|
||||
*
|
||||
* \param src the SDL_Surface structure to be copied from.
|
||||
* \param srcrect the SDL_Rect structure representing the rectangle to be
|
||||
* copied, or NULL to copy the entire surface.
|
||||
* \param dst the SDL_Surface structure that is the blit target.
|
||||
* \param dstrect the SDL_Rect structure representing the x and y position in
|
||||
* the destination surface, or NULL for (0,0). The width and
|
||||
* height are ignored, and are copied from `srcrect`. If you
|
||||
* want a specific width and height, you should use
|
||||
* SDL_BlitScaled().
|
||||
* \returns 0 if the blit is successful or a negative error code on failure;
|
||||
* call SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.0.
|
||||
*
|
||||
* \sa SDL_BlitSurface
|
||||
@@ -910,6 +931,13 @@ extern DECLSPEC int SDLCALL SDL_LowerBlit
|
||||
*
|
||||
* Please use SDL_BlitScaled() instead.
|
||||
*
|
||||
* \param src the surface to be copied from.
|
||||
* \param srcrect the rectangle to be copied.
|
||||
* \param dst the surface that is the blit target.
|
||||
* \param dstrect the rectangle that is copied into.
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.0.
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface * src,
|
||||
@@ -920,6 +948,13 @@ extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface * src,
|
||||
/**
|
||||
* Perform bilinear scaling between two surfaces of the same format, 32BPP.
|
||||
*
|
||||
* \param src the surface to be copied from.
|
||||
* \param srcrect the rectangle to be copied.
|
||||
* \param dst the surface that is the blit target.
|
||||
* \param dstrect the rectangle that is copied into.
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.16.
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_SoftStretchLinear(SDL_Surface * src,
|
||||
@@ -934,6 +969,15 @@ extern DECLSPEC int SDLCALL SDL_SoftStretchLinear(SDL_Surface * src,
|
||||
* SDL_UpperBlitScaled() has been replaced by SDL_BlitScaled(), which is
|
||||
* merely a macro for this function with a less confusing name.
|
||||
*
|
||||
* \param src the SDL_Surface structure to be copied from.
|
||||
* \param srcrect the SDL_Rect structure representing the rectangle to be
|
||||
* copied, or NULL to copy the entire surface.
|
||||
* \param dst the SDL_Surface structure that is the blit target.
|
||||
* \param dstrect the SDL_Rect structure representing the rectangle that is
|
||||
* copied into, or NULL to copy into the entire surface.
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.0.
|
||||
*
|
||||
* \sa SDL_BlitScaled
|
||||
@@ -971,6 +1015,8 @@ extern DECLSPEC int SDLCALL SDL_LowerBlitScaled
|
||||
/**
|
||||
* Set the YUV conversion mode
|
||||
*
|
||||
* \param mode the YUV conversion mode.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.8.
|
||||
*/
|
||||
extern DECLSPEC void SDLCALL SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE mode);
|
||||
@@ -978,6 +1024,8 @@ extern DECLSPEC void SDLCALL SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE mo
|
||||
/**
|
||||
* Get the YUV conversion mode
|
||||
*
|
||||
* \returns YUV conversion mode.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.8.
|
||||
*/
|
||||
extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionMode(void);
|
||||
@@ -986,6 +1034,10 @@ extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionMode(void);
|
||||
* Get the YUV conversion mode, returning the correct mode for the resolution
|
||||
* when the current conversion mode is SDL_YUV_CONVERSION_AUTOMATIC
|
||||
*
|
||||
* \param width the resolution width.
|
||||
* \param height the resolution height.
|
||||
* \returns YUV conversion mode.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.8.
|
||||
*/
|
||||
extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionModeForResolution(int width, int height);
|
||||
|
||||
@@ -463,6 +463,7 @@ extern DECLSPEC int SDLCALL SDL_AndroidShowToast(const char* message, int durati
|
||||
*
|
||||
* \param command user command that must be greater or equal to 0x8000.
|
||||
* \param param user parameter.
|
||||
* \returns 0 on success, otherwise -1.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.22.
|
||||
*/
|
||||
@@ -571,6 +572,26 @@ extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathT
|
||||
*/
|
||||
extern DECLSPEC SDL_WinRT_DeviceFamily SDLCALL SDL_WinRTGetDeviceFamily();
|
||||
|
||||
/**
|
||||
* Get the protocol activation URI if the app was launched via protocol
|
||||
* activation.
|
||||
*
|
||||
* When a UWP/WinRT app is launched via a custom URI scheme (e.g.,
|
||||
* myapp://action?param=value), this function retrieves the full activation
|
||||
* URI string.
|
||||
*
|
||||
* The URI is only available once per activation - after the first successful
|
||||
* call, subsequent calls will return NULL. This ensures the URI is processed
|
||||
* only once.
|
||||
*
|
||||
* \returns the protocol activation URI as a UTF-8 string that must be freed
|
||||
* with SDL_free(), or NULL if the app was not activated via protocol
|
||||
* or the URI was already retrieved.
|
||||
*
|
||||
* \since This function is available since SDL 2.33.0.
|
||||
*/
|
||||
extern DECLSPEC char * SDLCALL SDL_WinRTGetProtocolActivationURI(void);
|
||||
|
||||
#endif /* __WINRT__ */
|
||||
|
||||
/**
|
||||
|
||||
@@ -99,6 +99,10 @@ extern DECLSPEC SDL_TouchID SDLCALL SDL_GetTouchDevice(int index);
|
||||
* Get the touch device name as reported from the driver or NULL if the index
|
||||
* is invalid.
|
||||
*
|
||||
* \param index the touch device index.
|
||||
* \returns touch device name, or NULL on failure; call SDL_GetError() for
|
||||
* more information.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.22.
|
||||
*/
|
||||
extern DECLSPEC const char* SDLCALL SDL_GetTouchName(int index);
|
||||
@@ -106,6 +110,9 @@ extern DECLSPEC const char* SDLCALL SDL_GetTouchName(int index);
|
||||
/**
|
||||
* Get the type of the given touch device.
|
||||
*
|
||||
* \param touchID the ID of a touch device.
|
||||
* \returns touch device type.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.10.
|
||||
*/
|
||||
extern DECLSPEC SDL_TouchDeviceType SDLCALL SDL_GetTouchDeviceType(SDL_TouchID touchID);
|
||||
|
||||
@@ -57,8 +57,8 @@ typedef struct SDL_version
|
||||
/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
|
||||
*/
|
||||
#define SDL_MAJOR_VERSION 2
|
||||
#define SDL_MINOR_VERSION 32
|
||||
#define SDL_PATCHLEVEL 10
|
||||
#define SDL_MINOR_VERSION 33
|
||||
#define SDL_PATCHLEVEL 0
|
||||
|
||||
/**
|
||||
* Macro to determine SDL version program was compiled against.
|
||||
|
||||
@@ -1008,6 +1008,8 @@ extern DECLSPEC void SDLCALL SDL_GetWindowPosition(SDL_Window * window,
|
||||
* \param h the height of the window in pixels, in screen coordinates, must be
|
||||
* > 0.
|
||||
*
|
||||
* \threadsafety This function should only be called on the main thread.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.0.
|
||||
*
|
||||
* \sa SDL_GetWindowSize
|
||||
@@ -1315,6 +1317,7 @@ extern DECLSPEC int SDLCALL SDL_SetWindowFullscreen(SDL_Window * window,
|
||||
/**
|
||||
* Return whether the window has a surface associated with it.
|
||||
*
|
||||
* \param window the window to query.
|
||||
* \returns SDL_TRUE if there is a surface associated with the window, or
|
||||
* SDL_FALSE otherwise.
|
||||
*
|
||||
|
||||
@@ -678,6 +678,7 @@ static int SDLCALL SDL_RunAudio(void *userdata)
|
||||
int data_len = 0;
|
||||
Uint8 *data;
|
||||
Uint8 *device_buf_keepsafe = NULL;
|
||||
Uint32 delay;
|
||||
|
||||
SDL_assert(!device->iscapture);
|
||||
|
||||
@@ -761,7 +762,7 @@ static int SDLCALL SDL_RunAudio(void *userdata)
|
||||
SDL_assert((got <= 0) || (got == device->spec.size));
|
||||
|
||||
if (data == NULL) { /* device is having issues... */
|
||||
const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
|
||||
delay = ((device->spec.samples * 1000) / device->spec.freq);
|
||||
SDL_Delay(delay); /* wait for as long as this buffer would have played. Maybe device recovers later? */
|
||||
} else {
|
||||
if (got != device->spec.size) {
|
||||
@@ -781,7 +782,7 @@ static int SDLCALL SDL_RunAudio(void *userdata)
|
||||
}
|
||||
} else if (data == device->work_buffer) {
|
||||
/* nothing to do; pause like we queued a buffer to play. */
|
||||
const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
|
||||
delay = ((device->spec.samples * 1000) / device->spec.freq);
|
||||
SDL_Delay(delay);
|
||||
} else { /* writing directly to the device. */
|
||||
/* queue this buffer and wait for it to finish playing. */
|
||||
@@ -791,7 +792,11 @@ static int SDLCALL SDL_RunAudio(void *userdata)
|
||||
}
|
||||
|
||||
/* Wait for the audio to drain. */
|
||||
SDL_Delay(((device->spec.samples * 1000) / device->spec.freq) * 2);
|
||||
delay = ((device->spec.samples * 1000) / device->spec.freq) * 2;
|
||||
if (delay > 100) {
|
||||
delay = 100;
|
||||
}
|
||||
SDL_Delay(delay);
|
||||
|
||||
current_audio.impl.ThreadDeinit(device);
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ static int (*ALSA_snd_pcm_hw_params_set_access)(snd_pcm_t *, snd_pcm_hw_params_t
|
||||
static int (*ALSA_snd_pcm_hw_params_set_format)(snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_format_t);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_channels)(snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int);
|
||||
static int (*ALSA_snd_pcm_hw_params_get_channels)(const snd_pcm_hw_params_t *, unsigned int *);
|
||||
static int (*ALSA_snd_pcm_hw_params_get_rate)(const snd_pcm_hw_params_t *, unsigned int*, int*);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_rate_near)(snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int *, int *);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_period_size_near)(snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_uframes_t *, int *);
|
||||
static int (*ALSA_snd_pcm_hw_params_get_period_size)(const snd_pcm_hw_params_t *, snd_pcm_uframes_t *, int *);
|
||||
@@ -88,7 +89,7 @@ static const char *(*ALSA_snd_pcm_info_get_name)(const snd_pcm_info_t *);
|
||||
static int (*ALSA_snd_pcm_info_get_card)(const snd_pcm_info_t *);
|
||||
static int (*ALSA_snd_card_get_name)(int, char **);
|
||||
static int (*ALSA_snd_pcm_info_malloc)(snd_pcm_info_t **);
|
||||
static int (*ALSA_snd_pcm_info_free)(snd_pcm_info_t *);
|
||||
static void (*ALSA_snd_pcm_info_free)(snd_pcm_info_t *);
|
||||
#ifdef SND_CHMAP_API_VERSION
|
||||
static snd_pcm_chmap_t *(*ALSA_snd_pcm_get_chmap)(snd_pcm_t *);
|
||||
static int (*ALSA_snd_pcm_chmap_print)(const snd_pcm_chmap_t *map, size_t maxlen, char *buf);
|
||||
@@ -138,6 +139,7 @@ static int load_alsa_syms(void)
|
||||
SDL_ALSA_SYM(snd_pcm_hw_params_set_format);
|
||||
SDL_ALSA_SYM(snd_pcm_hw_params_set_channels);
|
||||
SDL_ALSA_SYM(snd_pcm_hw_params_get_channels);
|
||||
SDL_ALSA_SYM(snd_pcm_hw_params_get_rate);
|
||||
SDL_ALSA_SYM(snd_pcm_hw_params_set_rate_near);
|
||||
SDL_ALSA_SYM(snd_pcm_hw_params_set_period_size_near);
|
||||
SDL_ALSA_SYM(snd_pcm_hw_params_get_period_size);
|
||||
@@ -470,6 +472,9 @@ static void ALSA_CloseDevice(_THIS)
|
||||
ALSA_snd_pcm_drop() can hang, so don't use that.
|
||||
*/
|
||||
Uint32 delay = ((this->spec.samples * 1000) / this->spec.freq) * 2;
|
||||
if (delay > 100) {
|
||||
delay = 100;
|
||||
}
|
||||
SDL_Delay(delay);
|
||||
|
||||
ALSA_snd_pcm_close(this->hidden->pcm_handle);
|
||||
@@ -780,6 +785,16 @@ static void add_device(const int iscapture, const char *name, void *hint, ALSA_D
|
||||
char *desc;
|
||||
char *handle = NULL;
|
||||
char *ptr;
|
||||
snd_pcm_t *pcm_handle;
|
||||
snd_pcm_stream_t stream;
|
||||
snd_pcm_hw_params_t *hwparams;
|
||||
|
||||
unsigned int freq = 0;
|
||||
int dir;
|
||||
unsigned int channels = 0;
|
||||
snd_pcm_uframes_t samples = 0;
|
||||
|
||||
SDL_AudioSpec spec;
|
||||
|
||||
if (!dev) {
|
||||
return;
|
||||
@@ -819,12 +834,36 @@ static void add_device(const int iscapture, const char *name, void *hint, ALSA_D
|
||||
SDL_free(dev);
|
||||
return;
|
||||
}
|
||||
stream = iscapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK;
|
||||
|
||||
if (ALSA_snd_pcm_open(&pcm_handle, handle, stream, SND_PCM_NONBLOCK) < 0) {
|
||||
SDL_free(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Note that spec is NULL, because we are required to open the device before
|
||||
* acquiring the mix format, making this information inaccessible at
|
||||
* enumeration time
|
||||
*/
|
||||
SDL_AddAudioDevice(iscapture, desc, NULL, handle);
|
||||
snd_pcm_hw_params_alloca(&hwparams);
|
||||
ALSA_snd_pcm_hw_params_any(pcm_handle, hwparams);
|
||||
|
||||
ALSA_snd_pcm_hw_params_get_rate(hwparams, &freq, &dir);
|
||||
ALSA_snd_pcm_hw_params_get_channels(hwparams, &channels);
|
||||
ALSA_snd_pcm_hw_params_get_period_size(hwparams, &samples, &dir);
|
||||
|
||||
ALSA_snd_pcm_close(pcm_handle);
|
||||
|
||||
/* Let's fill the spec */
|
||||
|
||||
spec.freq = freq;
|
||||
spec.channels = channels;
|
||||
spec.samples = samples;
|
||||
spec.silence = 0;
|
||||
spec.padding = 0;
|
||||
/* Can't calculate size yet because this is an exploratory device opening
|
||||
* so we don't know the sample format.
|
||||
* Probably AUDIO_S16SYS/SND_PCM_FORMAT_S16_LE would be a good default
|
||||
* if required.*/
|
||||
spec.size = 0;
|
||||
|
||||
SDL_AddAudioDevice(iscapture, desc, &spec, handle);
|
||||
if (hint) {
|
||||
free(desc);
|
||||
}
|
||||
|
||||
@@ -199,6 +199,24 @@ static BOOL IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WO
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOL WIN_IsWine(void)
|
||||
{
|
||||
static SDL_bool checked;
|
||||
static SDL_bool is_wine;
|
||||
|
||||
if (!checked) {
|
||||
HMODULE ntdll = LoadLibrary(TEXT("ntdll.dll"));
|
||||
if (ntdll) {
|
||||
if (GetProcAddress(ntdll, "wine_get_version") != NULL) {
|
||||
is_wine = SDL_TRUE;
|
||||
}
|
||||
FreeLibrary(ntdll);
|
||||
}
|
||||
checked = SDL_TRUE;
|
||||
}
|
||||
return is_wine;
|
||||
}
|
||||
|
||||
BOOL WIN_IsWindowsVistaOrGreater(void)
|
||||
{
|
||||
#if defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)
|
||||
|
||||
@@ -136,6 +136,9 @@ extern void WIN_CoUninitialize(void);
|
||||
extern HRESULT WIN_RoInitialize(void);
|
||||
extern void WIN_RoUninitialize(void);
|
||||
|
||||
/* Returns true if we're running on Wine */
|
||||
extern BOOL WIN_IsWine(void);
|
||||
|
||||
/* Returns SDL_TRUE if we're running on Windows Vista and newer */
|
||||
extern BOOL WIN_IsWindowsVistaOrGreater(void);
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
/* Standard C++11 includes: */
|
||||
#include <string>
|
||||
/* Windows includes */
|
||||
#include "ppltasks.h"
|
||||
using namespace concurrency;
|
||||
@@ -43,6 +45,7 @@ extern "C" {
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_main.h"
|
||||
#include "SDL_stdinc.h"
|
||||
#include "SDL_system.h"
|
||||
#include "SDL_render.h"
|
||||
#include "../../video/SDL_sysvideo.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
@@ -80,6 +83,60 @@ extern "C" void D3D11_Trim(SDL_Renderer *);
|
||||
// SDL_CreateWindow().
|
||||
SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr;
|
||||
|
||||
// Protocol activation URI storage
|
||||
static Platform::String^ WINRT_ProtocolActivationURI = nullptr;
|
||||
|
||||
// Store launchOnExit URI separately since WINRT_ProtocolActivationURI gets cleared
|
||||
static std::wstring WINRT_LaunchOnExitURI;
|
||||
|
||||
// Helper function to extract and store launchOnExit from protocol URI
|
||||
static void WINRT_ExtractLaunchOnExitURI(Platform::String^ fullUri)
|
||||
{
|
||||
if (fullUri == nullptr)
|
||||
return;
|
||||
|
||||
std::wstring uri(fullUri->Data());
|
||||
|
||||
// Look for launchOnExit parameter in the URI
|
||||
size_t launchPos = uri.find(L"launchOnExit=");
|
||||
if (launchPos == std::wstring::npos)
|
||||
return;
|
||||
|
||||
// Extract the launchOnExit URI value
|
||||
launchPos += 13; // Skip past "launchOnExit="
|
||||
size_t endPos = uri.find(L'&', launchPos);
|
||||
if (endPos == std::wstring::npos)
|
||||
endPos = uri.length();
|
||||
|
||||
std::wstring launchUri = uri.substr(launchPos, endPos - launchPos);
|
||||
|
||||
// URL decode the URI (convert %3A to :, etc.)
|
||||
WINRT_LaunchOnExitURI.clear();
|
||||
for (size_t i = 0; i < launchUri.length(); i++) {
|
||||
if (launchUri[i] == L'%' && i + 2 < launchUri.length()) {
|
||||
wchar_t hex[3] = { launchUri[i + 1], launchUri[i + 2], 0 };
|
||||
WINRT_LaunchOnExitURI += (wchar_t)wcstol(hex, nullptr, 16);
|
||||
i += 2;
|
||||
} else {
|
||||
WINRT_LaunchOnExitURI += launchUri[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to launch URI on exit if protocol activation included launchOnExit parameter
|
||||
static void WINRT_LaunchExitUriIfSet()
|
||||
{
|
||||
if (!WINRT_LaunchOnExitURI.empty()) {
|
||||
try {
|
||||
// Launch the URI
|
||||
auto uri = ref new Windows::Foundation::Uri(ref new Platform::String(WINRT_LaunchOnExitURI.c_str()));
|
||||
Windows::System::Launcher::LaunchUriAsync(uri);
|
||||
} catch (...) {
|
||||
// Silently ignore errors during termination
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ref class SDLApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
|
||||
{
|
||||
public:
|
||||
@@ -107,6 +164,22 @@ int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **))
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" char* SDL_WinRTGetProtocolActivationURI(void)
|
||||
{
|
||||
if (WINRT_ProtocolActivationURI == nullptr)
|
||||
return nullptr;
|
||||
Platform::String^ uriStr = WINRT_ProtocolActivationURI;
|
||||
const wchar_t* uriWide = uriStr->Data();
|
||||
int uriLen = WideCharToMultiByte(CP_UTF8, 0, uriWide, -1, nullptr, 0, nullptr, nullptr);
|
||||
char* uriUtf8 = (char*)SDL_malloc(uriLen);
|
||||
if (uriUtf8)
|
||||
WideCharToMultiByte(CP_UTF8, 0, uriWide, -1, uriUtf8, uriLen, nullptr, nullptr);
|
||||
|
||||
// Clear after first successful read (only return it once)
|
||||
WINRT_ProtocolActivationURI = nullptr;
|
||||
return uriUtf8;
|
||||
}
|
||||
|
||||
static void WINRT_ProcessWindowSizeChange() // TODO: Pass an SDL_Window-identifying thing into WINRT_ProcessWindowSizeChange()
|
||||
{
|
||||
CoreWindow ^ coreWindow = CoreWindow::GetForCurrentThread();
|
||||
@@ -164,6 +237,12 @@ SDL_WinRTApp::SDL_WinRTApp() : m_windowClosed(false),
|
||||
{
|
||||
}
|
||||
|
||||
SDL_WinRTApp::~SDL_WinRTApp()
|
||||
{
|
||||
// Launch exit URI if set (handles protocol activation returning to caller)
|
||||
WINRT_LaunchExitUriIfSet();
|
||||
}
|
||||
|
||||
void SDL_WinRTApp::Initialize(CoreApplicationView ^ applicationView)
|
||||
{
|
||||
applicationView->Activated +=
|
||||
@@ -585,15 +664,29 @@ void SDL_WinRTApp::OnWindowClosed(CoreWindow ^ sender, CoreWindowEventArgs ^ arg
|
||||
SDL_Log("%s\n", __FUNCTION__);
|
||||
#endif
|
||||
m_windowClosed = true;
|
||||
WINRT_LaunchExitUriIfSet();
|
||||
}
|
||||
|
||||
void SDL_WinRTApp::OnAppActivated(CoreApplicationView ^ applicationView, IActivatedEventArgs ^ args)
|
||||
{
|
||||
if (args->Kind == Windows::ApplicationModel::Activation::ActivationKind::Protocol)
|
||||
{
|
||||
auto protocolArgs = dynamic_cast<Windows::ApplicationModel::Activation::ProtocolActivatedEventArgs^>(args);
|
||||
if (protocolArgs && protocolArgs->Uri)
|
||||
{
|
||||
WINRT_ProtocolActivationURI = protocolArgs->Uri->AbsoluteUri;
|
||||
// Extract and store launchOnExit URI before main URI gets cleared
|
||||
WINRT_ExtractLaunchOnExitURI(WINRT_ProtocolActivationURI);
|
||||
}
|
||||
}
|
||||
CoreWindow::GetForCurrentThread()->Activate();
|
||||
}
|
||||
|
||||
void SDL_WinRTApp::OnSuspending(Platform::Object ^ sender, SuspendingEventArgs ^ args)
|
||||
{
|
||||
// Launch exit URI if set before suspending
|
||||
WINRT_LaunchExitUriIfSet();
|
||||
|
||||
// Save app state asynchronously after requesting a deferral. Holding a deferral
|
||||
// indicates that the application is busy performing suspending operations. Be
|
||||
// aware that a deferral may not be held indefinitely. After about five seconds,
|
||||
@@ -647,6 +740,7 @@ void SDL_WinRTApp::OnResuming(Platform::Object ^ sender, Platform::Object ^ args
|
||||
void SDL_WinRTApp::OnExiting(Platform::Object ^ sender, Platform::Object ^ args)
|
||||
{
|
||||
SDL_SendAppEvent(SDL_APP_TERMINATING);
|
||||
WINRT_LaunchExitUriIfSet();
|
||||
}
|
||||
|
||||
static void WINRT_LogPointerEvent(const char *header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint)
|
||||
|
||||
@@ -26,6 +26,7 @@ ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFramewo
|
||||
{
|
||||
public:
|
||||
SDL_WinRTApp();
|
||||
virtual ~SDL_WinRTApp();
|
||||
|
||||
// IFrameworkView Methods.
|
||||
virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView ^ applicationView);
|
||||
|
||||
+10
-11
@@ -50,13 +50,12 @@
|
||||
#endif
|
||||
#if defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__))
|
||||
#include <sys/sysctl.h> /* For AltiVec check */
|
||||
#elif defined(__OpenBSD__) && defined(__powerpc__)
|
||||
#elif defined(__OpenBSD__) && defined(__powerpc__) && !defined(HAVE_ELF_AUX_INFO)
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h> /* For AltiVec check */
|
||||
#include <machine/cpu.h>
|
||||
#elif defined(__FreeBSD__) && defined(__powerpc__)
|
||||
#elif defined(__FreeBSD__) && defined(__powerpc__) && defined(HAVE_ELF_AUX_INFO)
|
||||
#include <machine/cpu.h>
|
||||
#include <sys/auxv.h>
|
||||
#elif defined(SDL_ALTIVEC_BLITTERS) && defined(HAVE_SETJMP)
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
@@ -343,7 +342,12 @@ static int CPU_haveAltiVec(void)
|
||||
{
|
||||
volatile int altivec = 0;
|
||||
#ifndef SDL_CPUINFO_DISABLED
|
||||
#if (defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__))) || (defined(__OpenBSD__) && defined(__powerpc__))
|
||||
#if (defined(__FreeBSD__) || defined(__OpenBSD__)) && defined(__powerpc__) && defined(HAVE_ELF_AUX_INFO)
|
||||
unsigned long cpufeatures = 0;
|
||||
elf_aux_info(AT_HWCAP, &cpufeatures, sizeof(cpufeatures));
|
||||
altivec = cpufeatures & PPC_FEATURE_HAS_ALTIVEC;
|
||||
return altivec;
|
||||
#elif (defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__))) || (defined(__OpenBSD__) && defined(__powerpc__))
|
||||
#ifdef __OpenBSD__
|
||||
int selectors[2] = { CTL_MACHDEP, CPU_ALTIVEC };
|
||||
#else
|
||||
@@ -355,11 +359,6 @@ static int CPU_haveAltiVec(void)
|
||||
if (0 == error) {
|
||||
altivec = (hasVectorUnit != 0);
|
||||
}
|
||||
#elif defined(__FreeBSD__) && defined(__powerpc__)
|
||||
unsigned long cpufeatures = 0;
|
||||
elf_aux_info(AT_HWCAP, &cpufeatures, sizeof(cpufeatures));
|
||||
altivec = cpufeatures & PPC_FEATURE_HAS_ALTIVEC;
|
||||
return altivec;
|
||||
#elif defined(__LINUX__) && defined(__powerpc__) && defined(HAVE_GETAUXVAL)
|
||||
altivec = getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC;
|
||||
#elif defined(SDL_ALTIVEC_BLITTERS) && defined(HAVE_SETJMP)
|
||||
@@ -489,8 +488,6 @@ static int CPU_haveNEON(void)
|
||||
return 0; /* assume anything else from Apple doesn't have NEON. */
|
||||
#elif !defined(__arm__)
|
||||
return 0; /* not an ARM CPU at all. */
|
||||
#elif defined(__OpenBSD__)
|
||||
return 1; /* OpenBSD only supports ARMv7 CPUs that have NEON. */
|
||||
#elif defined(HAVE_ELF_AUX_INFO)
|
||||
unsigned long hasneon = 0;
|
||||
if (elf_aux_info(AT_HWCAP, (void *)&hasneon, (int)sizeof(hasneon)) != 0) {
|
||||
@@ -527,6 +524,8 @@ static int CPU_haveNEON(void)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#elif defined(__OpenBSD__)
|
||||
return 1; /* OpenBSD only supports ARMv7 CPUs that have NEON. */
|
||||
#else
|
||||
#warning SDL_HasNEON is not implemented for this ARM platform. Write me.
|
||||
return 0;
|
||||
|
||||
@@ -872,3 +872,4 @@
|
||||
++'_SDL_DestroyWindowSurface'.'SDL2.dll'.'SDL_DestroyWindowSurface'
|
||||
# ++'_SDL_GDKGetDefaultUser'.'SDL2.dll'.'SDL_GDKGetDefaultUser'
|
||||
++'_SDL_GameControllerGetSteamHandle'.'SDL2.dll'.'SDL_GameControllerGetSteamHandle'
|
||||
# ++'_SDL_WinRTGetProtocolActivationURI'.'SDL2.dll'.'SDL_WinRTGetProtocolActivationURI'
|
||||
@@ -898,3 +898,4 @@
|
||||
#define SDL_DestroyWindowSurface SDL_DestroyWindowSurface_REAL
|
||||
#define SDL_GDKGetDefaultUser SDL_GDKGetDefaultUser_REAL
|
||||
#define SDL_GameControllerGetSteamHandle SDL_GameControllerGetSteamHandle_REAL
|
||||
#define SDL_WinRTGetProtocolActivationURI SDL_WinRTGetProtocolActivationURI_REAL
|
||||
@@ -985,3 +985,6 @@ SDL_DYNAPI_PROC(int,SDL_DestroyWindowSurface,(SDL_Window *a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GDKGetDefaultUser,(XUserHandle *a),(a),return)
|
||||
#endif
|
||||
SDL_DYNAPI_PROC(Uint64,SDL_GameControllerGetSteamHandle,(SDL_GameController *a),(a),return)
|
||||
#if defined(__WINRT__)
|
||||
SDL_DYNAPI_PROC(char*,SDL_WinRTGetProtocolActivationURI,(void),(),return)
|
||||
#endif
|
||||
@@ -1121,6 +1121,15 @@ int SDL_WarpMouseGlobal(int x, int y)
|
||||
|
||||
static SDL_bool ShouldUseRelativeModeWarp(SDL_Mouse *mouse)
|
||||
{
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND
|
||||
SDL_VideoDevice *vid = SDL_GetVideoDevice();
|
||||
|
||||
/* Wayland can't warp the mouse, but uses this hint internally to deliver accelerated motion */
|
||||
if (SDL_strcmp(vid->name, "wayland") == 0) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!mouse->WarpMouse) {
|
||||
/* Need this functionality for relative mode warp implementation */
|
||||
return SDL_FALSE;
|
||||
|
||||
@@ -49,8 +49,10 @@ static SDL_bool send_foregrounding_pending = SDL_FALSE;
|
||||
|
||||
static void SDL_HandleSIG(int sig)
|
||||
{
|
||||
/* Reset the signal handler */
|
||||
#ifndef HAVE_SIGACTION
|
||||
/* Reset the signal handler if it was installed with signal() */
|
||||
(void)signal(sig, SDL_HandleSIG);
|
||||
#endif
|
||||
|
||||
/* Send a quit event next time the event loop pumps. */
|
||||
/* We can't send it in signal handler; SDL_malloc() might be interrupted! */
|
||||
|
||||
@@ -1337,6 +1337,11 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned
|
||||
#endif
|
||||
#ifdef HAVE_LIBUSB
|
||||
for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) {
|
||||
if (use_libusb_whitelist) {
|
||||
if (!IsInWhitelist(usb_dev->vendor_id, usb_dev->product_id)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (raw_dev->vendor_id == usb_dev->vendor_id &&
|
||||
raw_dev->product_id == usb_dev->product_id &&
|
||||
(raw_dev->interface_number < 0 || raw_dev->interface_number == usb_dev->interface_number)) {
|
||||
|
||||
@@ -37,6 +37,10 @@
|
||||
#include "../events/SDL_events_c.h"
|
||||
#endif
|
||||
|
||||
#if defined(__WIN32__)
|
||||
#include "../core/windows/SDL_windows.h"
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#include "SDL_system.h"
|
||||
#endif
|
||||
@@ -1984,7 +1988,7 @@ const char *SDL_GameControllerPathForIndex(int joystick_index)
|
||||
SDL_GameControllerType SDL_GameControllerTypeForIndex(int joystick_index)
|
||||
{
|
||||
SDL_JoystickGUID joystick_guid = SDL_JoystickGetDeviceGUID(joystick_index);
|
||||
const char *mapping = SDL_GameControllerMappingForGUID(joystick_guid);
|
||||
char *mapping = SDL_GameControllerMappingForGUID(joystick_guid);
|
||||
char *type_string, *comma;
|
||||
SDL_GameControllerType type;
|
||||
if (mapping) {
|
||||
@@ -1999,8 +2003,10 @@ SDL_GameControllerType SDL_GameControllerTypeForIndex(int joystick_index)
|
||||
} else {
|
||||
type = SDL_GetGameControllerTypeFromString(type_string);
|
||||
}
|
||||
SDL_free(mapping);
|
||||
return type;
|
||||
}
|
||||
SDL_free(mapping);
|
||||
}
|
||||
return SDL_GetJoystickGameControllerTypeFromGUID(joystick_guid, SDL_JoystickNameForIndex(joystick_index));
|
||||
}
|
||||
@@ -2128,7 +2134,7 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
|
||||
|
||||
#ifdef __WIN32__
|
||||
if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE) &&
|
||||
SDL_GetHintBoolean("STEAM_COMPAT_PROTON", SDL_FALSE)) {
|
||||
WIN_IsWine()) {
|
||||
/* We are launched by Steam and running under Proton
|
||||
* We can't tell whether this controller is a Steam Virtual Gamepad,
|
||||
* so assume that Proton is doing the appropriate filtering of controllers
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef __LINUX__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define SDL_HINT_STEAM_VIRTUAL_GAMEPAD_INFO_FILE "SteamVirtualGamepadInfo"
|
||||
|
||||
@@ -123,6 +126,28 @@ static void AddVirtualGamepadInfo(int slot, SDL_SteamVirtualGamepadInfo *info)
|
||||
SDL_zerop(info);
|
||||
}
|
||||
|
||||
#ifdef __LINUX__
|
||||
static const char *SDL_GetExeName(void)
|
||||
{
|
||||
const char *proc_name = NULL;
|
||||
static char linkfile[1024];
|
||||
int linksize;
|
||||
const char *proc_path = "/proc/self/exe";
|
||||
|
||||
linksize = readlink(proc_path, linkfile, sizeof(linkfile) - 1);
|
||||
if (linksize > 0) {
|
||||
linkfile[linksize] = '\0';
|
||||
proc_name = SDL_strrchr(linkfile, '/');
|
||||
if (proc_name) {
|
||||
++proc_name;
|
||||
} else {
|
||||
proc_name = linkfile;
|
||||
}
|
||||
}
|
||||
return proc_name;
|
||||
}
|
||||
#endif /* __LINUX__ */
|
||||
|
||||
void SDL_InitSteamVirtualGamepadInfo(void)
|
||||
{
|
||||
const char *file;
|
||||
@@ -131,6 +156,16 @@ void SDL_InitSteamVirtualGamepadInfo(void)
|
||||
|
||||
file = SDL_GetHint(SDL_HINT_STEAM_VIRTUAL_GAMEPAD_INFO_FILE);
|
||||
if (file && *file) {
|
||||
#ifdef __LINUX__
|
||||
/* Older versions of Wine will blacklist the Steam Virtual Gamepad if
|
||||
* it appears to have the real controller's VID/PID, so ignore this.
|
||||
*/
|
||||
const char *exe = SDL_GetExeName();
|
||||
if (exe && SDL_strcmp(exe, "wine64-preloader") == 0) {
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "Wine launched by Steam, ignoring %s", SDL_HINT_STEAM_VIRTUAL_GAMEPAD_INFO_FILE);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
SDL_steam_virtual_gamepad_info_file = SDL_strdup(file);
|
||||
}
|
||||
SDL_UpdateSteamVirtualGamepadInfo();
|
||||
|
||||
@@ -40,17 +40,18 @@ static int numjoysticks = 0;
|
||||
|
||||
static EM_BOOL Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData)
|
||||
{
|
||||
SDL_joylist_item *item;
|
||||
int i;
|
||||
|
||||
SDL_joylist_item *item;
|
||||
SDL_LockJoysticks();
|
||||
|
||||
if (JoystickByIndex(gamepadEvent->index) != NULL) {
|
||||
return 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
item = (SDL_joylist_item *)SDL_malloc(sizeof(SDL_joylist_item));
|
||||
if (!item) {
|
||||
return 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
SDL_zerop(item);
|
||||
@@ -59,14 +60,14 @@ static EM_BOOL Emscripten_JoyStickConnected(int eventType, const EmscriptenGamep
|
||||
item->name = SDL_CreateJoystickName(0, 0, NULL, gamepadEvent->id);
|
||||
if (!item->name) {
|
||||
SDL_free(item);
|
||||
return 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
item->mapping = SDL_strdup(gamepadEvent->mapping);
|
||||
if (!item->mapping) {
|
||||
SDL_free(item->name);
|
||||
SDL_free(item);
|
||||
return 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
item->naxes = gamepadEvent->numAxes;
|
||||
@@ -103,6 +104,9 @@ static EM_BOOL Emscripten_JoyStickConnected(int eventType, const EmscriptenGamep
|
||||
SDL_Log("Added joystick with index %d", item->index);
|
||||
#endif
|
||||
|
||||
done:
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -111,6 +115,8 @@ static EM_BOOL Emscripten_JoyStickDisconnected(int eventType, const EmscriptenGa
|
||||
SDL_joylist_item *item = SDL_joylist;
|
||||
SDL_joylist_item *prev = NULL;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
|
||||
while (item) {
|
||||
if (item->index == gamepadEvent->index) {
|
||||
break;
|
||||
@@ -120,7 +126,7 @@ static EM_BOOL Emscripten_JoyStickDisconnected(int eventType, const EmscriptenGa
|
||||
}
|
||||
|
||||
if (!item) {
|
||||
return 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (item->joystick) {
|
||||
@@ -148,6 +154,10 @@ static EM_BOOL Emscripten_JoyStickDisconnected(int eventType, const EmscriptenGa
|
||||
SDL_free(item->name);
|
||||
SDL_free(item->mapping);
|
||||
SDL_free(item);
|
||||
|
||||
done:
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -644,13 +644,6 @@ static void RotatePad(int *pX, int *pY, float flAngleInRad)
|
||||
*pX = (int)(SDL_cosf(flAngleInRad) * origX - SDL_sinf(flAngleInRad) * origY);
|
||||
*pY = (int)(SDL_sinf(flAngleInRad) * origX + SDL_cosf(flAngleInRad) * origY);
|
||||
}
|
||||
static void RotatePadShort(short *pX, short *pY, float flAngleInRad)
|
||||
{
|
||||
short int origX = *pX, origY = *pY;
|
||||
|
||||
*pX = (short)(SDL_cosf(flAngleInRad) * origX - SDL_sinf(flAngleInRad) * origY);
|
||||
*pY = (short)(SDL_sinf(flAngleInRad) * origX + SDL_cosf(flAngleInRad) * origY);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Format the first part of the state packet
|
||||
@@ -774,9 +767,16 @@ static void FormatStatePacketUntilGyro(SteamControllerStateInternal_t *pState, V
|
||||
//---------------------------------------------------------------------------
|
||||
static bool UpdateBLESteamControllerState(const uint8_t *pData, int nDataSize, SteamControllerStateInternal_t *pState)
|
||||
{
|
||||
const float flRotationAngle = 0.261799f;
|
||||
int nLeftPadX;
|
||||
int nLeftPadY;
|
||||
int nRightPadX;
|
||||
int nRightPadY;
|
||||
int nPadOffset;
|
||||
uint32_t ucOptionDataMask;
|
||||
|
||||
// 15 degrees in rad
|
||||
const float flRotationAngle = 0.261799f;
|
||||
|
||||
pState->unPacketNum++;
|
||||
ucOptionDataMask = (*pData++ & 0xF0);
|
||||
ucOptionDataMask |= (uint32_t)(*pData++) << 8;
|
||||
@@ -805,7 +805,6 @@ static bool UpdateBLESteamControllerState(const uint8_t *pData, int nDataSize, S
|
||||
}
|
||||
if (ucOptionDataMask & k_EBLELeftTrackpadChunk) {
|
||||
int nLength = sizeof(pState->sLeftPadX) + sizeof(pState->sLeftPadY);
|
||||
int nPadOffset;
|
||||
SDL_memcpy(&pState->sLeftPadX, pData, nLength);
|
||||
if (pState->ulButtons & STEAM_LEFTPAD_FINGERDOWN_MASK) {
|
||||
nPadOffset = 1000;
|
||||
@@ -813,14 +812,15 @@ static bool UpdateBLESteamControllerState(const uint8_t *pData, int nDataSize, S
|
||||
nPadOffset = 0;
|
||||
}
|
||||
|
||||
RotatePadShort(&pState->sLeftPadX, &pState->sLeftPadY, -flRotationAngle);
|
||||
pState->sLeftPadX = clamp(pState->sLeftPadX + nPadOffset, SDL_MIN_SINT16, SDL_MAX_SINT16);
|
||||
pState->sLeftPadY = clamp(pState->sLeftPadY + nPadOffset, SDL_MIN_SINT16, SDL_MAX_SINT16);
|
||||
nLeftPadX = pState->sLeftPadX;
|
||||
nLeftPadY = pState->sLeftPadY;
|
||||
RotatePad(&nLeftPadX, &nLeftPadY, -flRotationAngle);
|
||||
pState->sLeftPadX = (short)clamp(nLeftPadX + nPadOffset, SDL_MIN_SINT16, SDL_MAX_SINT16);
|
||||
pState->sLeftPadY = (short)clamp(nLeftPadY + nPadOffset, SDL_MIN_SINT16, SDL_MAX_SINT16);
|
||||
pData += nLength;
|
||||
}
|
||||
if (ucOptionDataMask & k_EBLERightTrackpadChunk) {
|
||||
int nLength = sizeof(pState->sRightPadX) + sizeof(pState->sRightPadY);
|
||||
int nPadOffset = 0;
|
||||
|
||||
SDL_memcpy(&pState->sRightPadX, pData, nLength);
|
||||
|
||||
@@ -830,9 +830,11 @@ static bool UpdateBLESteamControllerState(const uint8_t *pData, int nDataSize, S
|
||||
nPadOffset = 0;
|
||||
}
|
||||
|
||||
RotatePadShort(&pState->sRightPadX, &pState->sRightPadY, flRotationAngle);
|
||||
pState->sRightPadX = clamp(pState->sRightPadX + nPadOffset, SDL_MIN_SINT16, SDL_MAX_SINT16);
|
||||
pState->sRightPadY = clamp(pState->sRightPadY + nPadOffset, SDL_MIN_SINT16, SDL_MAX_SINT16);
|
||||
nRightPadX = pState->sRightPadX;
|
||||
nRightPadY = pState->sRightPadY;
|
||||
RotatePad(&nRightPadX, &nRightPadY, flRotationAngle);
|
||||
pState->sRightPadX = (short)clamp(nRightPadX + nPadOffset, SDL_MIN_SINT16, SDL_MAX_SINT16);
|
||||
pState->sRightPadY = (short)clamp(nRightPadY + nPadOffset, SDL_MIN_SINT16, SDL_MAX_SINT16);
|
||||
pData += nLength;
|
||||
}
|
||||
if (ucOptionDataMask & k_EBLEIMUAccelChunk) {
|
||||
|
||||
@@ -1027,7 +1027,7 @@ static int RAWINPUT_JoystickInit(void)
|
||||
{
|
||||
SDL_assert(!SDL_RAWINPUT_inited);
|
||||
|
||||
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, SDL_TRUE)) {
|
||||
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, SDL_FALSE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 2,32,10,0
|
||||
PRODUCTVERSION 2,32,10,0
|
||||
FILEVERSION 2,33,0,0
|
||||
PRODUCTVERSION 2,33,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
FILEFLAGS 0x0L
|
||||
FILEOS 0x40004L
|
||||
@@ -23,12 +23,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "\0"
|
||||
VALUE "FileDescription", "SDL\0"
|
||||
VALUE "FileVersion", "2, 32, 10, 0\0"
|
||||
VALUE "FileVersion", "2, 33, 0, 0\0"
|
||||
VALUE "InternalName", "SDL\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0"
|
||||
VALUE "OriginalFilename", "SDL2.dll\0"
|
||||
VALUE "ProductName", "Simple DirectMedia Layer\0"
|
||||
VALUE "ProductVersion", "2, 32, 10, 0\0"
|
||||
VALUE "ProductVersion", "2, 33, 0, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -29,6 +29,12 @@
|
||||
#include "software/SDL_render_sw_c.h"
|
||||
#include "../video/SDL_pixels_c.h"
|
||||
|
||||
#if defined(__loongarch__)
|
||||
#if SDL_VIDEO_OPENGL
|
||||
#include "SDL_opengl.h"
|
||||
#endif /* SDL_VIDEO_OPENGL */
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#include "../core/android/SDL_android.h"
|
||||
#endif
|
||||
@@ -954,6 +960,34 @@ static void SDL_CalculateSimulatedVSyncInterval(SDL_Renderer *renderer, SDL_Wind
|
||||
}
|
||||
#endif /* !SDL_RENDER_DISABLED */
|
||||
|
||||
#if defined(__loongarch__)
|
||||
static SDL_bool SDL_CheckIntegratedGraphics()
|
||||
{
|
||||
SDL_Window *window = SDL_CreateWindow("OpenGL test", -32, -32, 32, 32,
|
||||
SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
|
||||
SDL_bool has_lg100_or_lg110 = SDL_FALSE;
|
||||
|
||||
if (window) {
|
||||
SDL_GLContext context = SDL_GL_CreateContext(window);
|
||||
|
||||
if (context) {
|
||||
const GLubyte *(APIENTRY *glGetStringFunc)(GLenum) =
|
||||
SDL_GL_GetProcAddress("glGetString");
|
||||
if (glGetStringFunc) {
|
||||
const char *renderer = (const char*)glGetStringFunc(GL_RENDERER);
|
||||
if (renderer && (SDL_strstr(renderer, "LG110") ||
|
||||
SDL_strstr(renderer, "LG100"))) {
|
||||
has_lg100_or_lg110 = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
SDL_GL_DeleteContext(context);
|
||||
}
|
||||
SDL_DestroyWindow(window);
|
||||
}
|
||||
return has_lg100_or_lg110;
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_Renderer *SDL_CreateRenderer(SDL_Window *window, int index, Uint32 flags)
|
||||
{
|
||||
#ifndef SDL_RENDER_DISABLED
|
||||
@@ -967,6 +1001,14 @@ SDL_Renderer *SDL_CreateRenderer(SDL_Window *window, int index, Uint32 flags)
|
||||
Android_ActivityMutex_Lock_Running();
|
||||
#endif
|
||||
|
||||
/* CPU acceleration runs faster than integrated graphics on Loongson at present. */
|
||||
#if defined(__linux__) && defined(__loongarch__)
|
||||
if (SDL_CheckIntegratedGraphics()) {
|
||||
SDL_SetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION, "0");
|
||||
flags = SDL_RENDERER_SOFTWARE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!window) {
|
||||
SDL_InvalidParamError("window");
|
||||
goto error;
|
||||
|
||||
@@ -624,8 +624,42 @@ static int PS2_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, Uint32
|
||||
|
||||
gsGlobal = gsKit_init_global_custom(RENDER_QUEUE_OS_POOLSIZE, RENDER_QUEUE_PER_POOLSIZE);
|
||||
|
||||
gsGlobal->Mode = GS_MODE_NTSC;
|
||||
gsGlobal->Height = 448;
|
||||
// GS interlaced/progressive
|
||||
if (SDL_GetHintBoolean(SDL_HINT_PS2_GS_PROGRESSIVE, false)) {
|
||||
gsGlobal->Interlace = GS_NONINTERLACED;
|
||||
} else {
|
||||
gsGlobal->Interlace = GS_INTERLACED;
|
||||
}
|
||||
|
||||
// GS width/height
|
||||
gsGlobal->Width = 0;
|
||||
gsGlobal->Height = 0;
|
||||
const char *hint = SDL_GetHint(SDL_HINT_PS2_GS_WIDTH);
|
||||
if (hint) {
|
||||
gsGlobal->Width = SDL_atoi(hint);
|
||||
}
|
||||
hint = SDL_GetHint(SDL_HINT_PS2_GS_HEIGHT);
|
||||
if (hint) {
|
||||
gsGlobal->Height = SDL_atoi(hint);
|
||||
}
|
||||
if (gsGlobal->Width <= 0) {
|
||||
gsGlobal->Width = 640;
|
||||
}
|
||||
if (gsGlobal->Height <= 0) {
|
||||
gsGlobal->Height = 448;
|
||||
}
|
||||
|
||||
// GS region
|
||||
hint = SDL_GetHint(SDL_HINT_PS2_GS_MODE);
|
||||
if (hint) {
|
||||
if (SDL_strcasecmp(SDL_GetHint(SDL_HINT_PS2_GS_MODE), "NTSC") == 0) {
|
||||
gsGlobal->Mode = GS_MODE_NTSC;
|
||||
}
|
||||
|
||||
if (SDL_strcasecmp(SDL_GetHint(SDL_HINT_PS2_GS_MODE), "PAL") == 0) {
|
||||
gsGlobal->Mode = GS_MODE_PAL;
|
||||
}
|
||||
}
|
||||
|
||||
gsGlobal->PSM = GS_PSM_CT24;
|
||||
gsGlobal->PSMZ = GS_PSMZ_16S;
|
||||
|
||||
+178
-16
@@ -76,6 +76,24 @@ typedef struct
|
||||
SDL_Texture *texture;
|
||||
} PSP_BlendState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SDL_Rect viewport;
|
||||
SDL_bool viewport_dirty;
|
||||
SDL_bool viewport_is_set;
|
||||
|
||||
SDL_bool cliprect_enabled_dirty;
|
||||
SDL_bool cliprect_enabled;
|
||||
SDL_bool cliprect_dirty;
|
||||
SDL_Rect cliprect;
|
||||
|
||||
float draw_offset_x;
|
||||
float draw_offset_y;
|
||||
|
||||
int drawablew;
|
||||
int drawableh;
|
||||
} PSP_DrawstateCache;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *frontbuffer; /**< main screen buffer */
|
||||
@@ -91,6 +109,7 @@ typedef struct
|
||||
PSP_TextureData *most_recent_target; /**< start of render target LRU double linked list */
|
||||
PSP_TextureData *least_recent_target; /**< end of the LRU list */
|
||||
|
||||
PSP_DrawstateCache drawstate;
|
||||
SDL_bool vblank_not_reached; /**< whether vblank wasn't reached */
|
||||
} PSP_RenderData;
|
||||
|
||||
@@ -1034,10 +1053,105 @@ static void PSP_SetBlendState(PSP_RenderData *data, PSP_BlendState *state)
|
||||
*current = *state;
|
||||
}
|
||||
|
||||
static void ClampCliprectToViewport(SDL_Rect *clip, const SDL_Rect *viewport)
|
||||
{
|
||||
int max_x_v, max_y_v, max_x_c, max_y_c;
|
||||
|
||||
if (clip->x < 0) {
|
||||
clip->w += clip->x;
|
||||
clip->x = 0;
|
||||
}
|
||||
|
||||
if (clip->y < 0) {
|
||||
clip->h += clip->y;
|
||||
clip->y = 0;
|
||||
}
|
||||
|
||||
max_x_c = clip->x + clip->w;
|
||||
max_y_c = clip->y + clip->h;
|
||||
|
||||
max_x_v = viewport->x + viewport->w;
|
||||
max_y_v = viewport->y + viewport->h;
|
||||
|
||||
if (max_x_c > max_x_v) {
|
||||
clip->w -= (max_x_v - max_x_c);
|
||||
}
|
||||
|
||||
if (max_y_c > max_y_v) {
|
||||
clip->h -= (max_y_v - max_y_c);
|
||||
}
|
||||
}
|
||||
|
||||
static void SetDrawState(PSP_RenderData *data)
|
||||
{
|
||||
if (data->drawstate.viewport_dirty) {
|
||||
SDL_Rect *viewport = &data->drawstate.viewport;
|
||||
/* FIXME: Find a genuine way to make viewport work (right now calling these functions here give no effect) */
|
||||
/*
|
||||
sceGuOffset(2048 - (480 >> 1) + viewport->x, 2048 - (272 >> 1) + viewport->y);
|
||||
sceGuViewport(2048, 2048, viewport->w, viewport->h);
|
||||
*/
|
||||
data->drawstate.draw_offset_x = viewport->x;
|
||||
data->drawstate.draw_offset_y = viewport->y;
|
||||
data->drawstate.viewport_dirty = SDL_FALSE;
|
||||
}
|
||||
|
||||
if (data->drawstate.cliprect_enabled_dirty) {
|
||||
if (!data->drawstate.cliprect_enabled && !data->drawstate.viewport_is_set) {
|
||||
sceGuScissor(0, 0, data->drawstate.drawablew, data->drawstate.drawableh);
|
||||
sceGuEnable(GU_SCISSOR_TEST);
|
||||
}
|
||||
data->drawstate.cliprect_enabled_dirty = SDL_FALSE;
|
||||
}
|
||||
|
||||
if ((data->drawstate.cliprect_enabled || data->drawstate.viewport_is_set) && data->drawstate.cliprect_dirty) {
|
||||
SDL_Rect rect;
|
||||
SDL_Rect *viewport = &data->drawstate.viewport;
|
||||
SDL_copyp(&rect, &data->drawstate.cliprect);
|
||||
if (data->drawstate.viewport_is_set) {
|
||||
ClampCliprectToViewport(&rect, viewport);
|
||||
rect.x += viewport->x;
|
||||
rect.y += viewport->y;
|
||||
}
|
||||
sceGuEnable(GU_SCISSOR_TEST);
|
||||
sceGuScissor(rect.x, rect.y, rect.w, rect.h);
|
||||
data->drawstate.cliprect_dirty = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#define PSP_VERTICES_FUNK(FunkName, Type) \
|
||||
static const Type *FunkName(const PSP_DrawstateCache *drawstate, Uint8 *gpumem, SDL_RenderCommand *cmd, size_t count) \
|
||||
{ \
|
||||
size_t i; \
|
||||
float off_x, off_y; \
|
||||
Type *verts = (Type *)(gpumem + cmd->data.draw.first); \
|
||||
\
|
||||
if (!drawstate->viewport_is_set) { \
|
||||
return verts; \
|
||||
} \
|
||||
\
|
||||
off_x = drawstate->draw_offset_x; \
|
||||
off_y = drawstate->draw_offset_y; \
|
||||
\
|
||||
for (i = 0; i < count; ++i) { \
|
||||
verts[i].x += off_x; \
|
||||
verts[i].y += off_y; \
|
||||
} \
|
||||
\
|
||||
return verts;\
|
||||
}
|
||||
|
||||
PSP_VERTICES_FUNK(PSP_GetVertV, VertV)
|
||||
PSP_VERTICES_FUNK(PSP_GetVertTV, VertTV)
|
||||
PSP_VERTICES_FUNK(PSP_GetVertCV, VertCV)
|
||||
PSP_VERTICES_FUNK(PSP_GetVertTCV, VertTCV)
|
||||
|
||||
static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
|
||||
{
|
||||
PSP_RenderData *data = (PSP_RenderData *)renderer->driverdata;
|
||||
Uint8 *gpumem = NULL;
|
||||
int w = 0, h = 0;
|
||||
|
||||
StartDrawing(renderer);
|
||||
|
||||
/* note that before the renderer interface change, this would do extrememly small
|
||||
@@ -1052,6 +1166,21 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||
}
|
||||
SDL_memcpy(gpumem, vertices, vertsize);
|
||||
|
||||
if (!data->boundTarget) {
|
||||
SDL_GL_GetDrawableSize(renderer->window, &w, &h);
|
||||
} else {
|
||||
PSP_TextureData *psp_texture = (PSP_TextureData *)data->boundTarget->driverdata;
|
||||
w = psp_texture->width;
|
||||
h = psp_texture->height;
|
||||
}
|
||||
|
||||
if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) {
|
||||
data->drawstate.viewport_dirty = SDL_TRUE; /* if the window dimensions changed, invalidate the current viewport, etc. */
|
||||
data->drawstate.cliprect_dirty = SDL_TRUE;
|
||||
data->drawstate.drawablew = w;
|
||||
data->drawstate.drawableh = h;
|
||||
}
|
||||
|
||||
while (cmd) {
|
||||
switch (cmd->command) {
|
||||
case SDL_RENDERCMD_SETDRAWCOLOR:
|
||||
@@ -1061,22 +1190,42 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||
|
||||
case SDL_RENDERCMD_SETVIEWPORT:
|
||||
{
|
||||
SDL_Rect *viewport = &cmd->data.viewport.rect;
|
||||
sceGuOffset(2048 - (viewport->w >> 1), 2048 - (viewport->h >> 1));
|
||||
sceGuViewport(2048, 2048, viewport->w, viewport->h);
|
||||
sceGuScissor(viewport->x, viewport->y, viewport->w, viewport->h);
|
||||
/* FIXME: We need to update the clip rect too, see https://github.com/libsdl-org/SDL/issues/9094 */
|
||||
SDL_Rect *viewport = &data->drawstate.viewport;
|
||||
if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) {
|
||||
SDL_copyp(viewport, &cmd->data.viewport.rect);
|
||||
data->drawstate.viewport_dirty = SDL_TRUE;
|
||||
data->drawstate.cliprect_dirty = SDL_TRUE;
|
||||
data->drawstate.viewport_is_set = viewport->x != 0 || viewport->y != 0 || viewport->w != data->drawstate.drawablew || viewport->h != data->drawstate.drawableh;
|
||||
if (!data->drawstate.cliprect_enabled) {
|
||||
if (data->drawstate.viewport_is_set) {
|
||||
SDL_copyp(&data->drawstate.cliprect, viewport);
|
||||
data->drawstate.cliprect.x = 0;
|
||||
data->drawstate.cliprect.y = 0;
|
||||
} else {
|
||||
data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETCLIPRECT:
|
||||
{
|
||||
const SDL_Rect *rect = &cmd->data.cliprect.rect;
|
||||
if (cmd->data.cliprect.enabled) {
|
||||
sceGuEnable(GU_SCISSOR_TEST);
|
||||
sceGuScissor(rect->x, rect->y, rect->w, rect->h);
|
||||
} else {
|
||||
sceGuDisable(GU_SCISSOR_TEST);
|
||||
const SDL_Rect *viewport = &data->drawstate.viewport;
|
||||
if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) {
|
||||
data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
|
||||
data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
|
||||
if (!data->drawstate.cliprect_enabled && data->drawstate.viewport_is_set) {
|
||||
SDL_copyp(&data->drawstate.cliprect, viewport);
|
||||
data->drawstate.cliprect.x = 0;
|
||||
data->drawstate.cliprect.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof(*rect)) != 0) {
|
||||
SDL_copyp(&data->drawstate.cliprect, rect);
|
||||
data->drawstate.cliprect_dirty = SDL_TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1087,6 +1236,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||
const Uint8 g = cmd->data.color.g;
|
||||
const Uint8 b = cmd->data.color.b;
|
||||
const Uint8 a = cmd->data.color.a;
|
||||
SetDrawState(data);
|
||||
sceGuClearColor(GU_RGBA(r, g, b, a));
|
||||
sceGuClearStencil(a);
|
||||
sceGuClear(GU_COLOR_BUFFER_BIT | GU_STENCIL_BUFFER_BIT);
|
||||
@@ -1096,7 +1246,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||
case SDL_RENDERCMD_DRAW_POINTS:
|
||||
{
|
||||
const size_t count = cmd->data.draw.count;
|
||||
const VertV *verts = (VertV *)(gpumem + cmd->data.draw.first);
|
||||
const VertV *verts; /* = (VertV *)(gpumem + cmd->data.draw.first);*/
|
||||
const Uint8 r = cmd->data.draw.r;
|
||||
const Uint8 g = cmd->data.draw.g;
|
||||
const Uint8 b = cmd->data.draw.b;
|
||||
@@ -1107,6 +1257,8 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||
.mode = cmd->data.draw.blend,
|
||||
.shadeModel = GU_FLAT
|
||||
};
|
||||
SetDrawState(data);
|
||||
verts = PSP_GetVertV(&data->drawstate, gpumem, cmd, count);
|
||||
PSP_SetBlendState(data, &state);
|
||||
sceGuDrawArray(GU_POINTS, GU_VERTEX_32BITF | GU_TRANSFORM_2D, count, 0, verts);
|
||||
break;
|
||||
@@ -1115,7 +1267,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||
case SDL_RENDERCMD_DRAW_LINES:
|
||||
{
|
||||
const size_t count = cmd->data.draw.count;
|
||||
const VertV *verts = (VertV *)(gpumem + cmd->data.draw.first);
|
||||
const VertV *verts; /* = (VertV *)(gpumem + cmd->data.draw.first);*/
|
||||
const Uint8 r = cmd->data.draw.r;
|
||||
const Uint8 g = cmd->data.draw.g;
|
||||
const Uint8 b = cmd->data.draw.b;
|
||||
@@ -1126,6 +1278,8 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||
.mode = cmd->data.draw.blend,
|
||||
.shadeModel = GU_FLAT
|
||||
};
|
||||
SetDrawState(data);
|
||||
verts = PSP_GetVertV(&data->drawstate, gpumem, cmd, count);
|
||||
PSP_SetBlendState(data, &state);
|
||||
sceGuDrawArray(GU_LINE_STRIP, GU_VERTEX_32BITF | GU_TRANSFORM_2D, count, 0, verts);
|
||||
break;
|
||||
@@ -1134,7 +1288,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||
case SDL_RENDERCMD_FILL_RECTS:
|
||||
{
|
||||
const size_t count = cmd->data.draw.count;
|
||||
const VertV *verts = (VertV *)(gpumem + cmd->data.draw.first);
|
||||
const VertV *verts; /* = (VertV *)(gpumem + cmd->data.draw.first);*/
|
||||
const Uint8 r = cmd->data.draw.r;
|
||||
const Uint8 g = cmd->data.draw.g;
|
||||
const Uint8 b = cmd->data.draw.b;
|
||||
@@ -1145,6 +1299,8 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||
.mode = cmd->data.draw.blend,
|
||||
.shadeModel = GU_FLAT
|
||||
};
|
||||
SetDrawState(data);
|
||||
verts = PSP_GetVertV(&data->drawstate, gpumem, cmd, 2 * count);
|
||||
PSP_SetBlendState(data, &state);
|
||||
sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF | GU_TRANSFORM_2D, 2 * count, 0, verts);
|
||||
break;
|
||||
@@ -1153,7 +1309,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||
case SDL_RENDERCMD_COPY:
|
||||
{
|
||||
const size_t count = cmd->data.draw.count;
|
||||
const VertTV *verts = (VertTV *)(gpumem + cmd->data.draw.first);
|
||||
const VertTV *verts; /*= (VertTV *)(gpumem + cmd->data.draw.first);*/
|
||||
const Uint8 a = cmd->data.draw.a;
|
||||
const Uint8 r = cmd->data.draw.r;
|
||||
const Uint8 g = cmd->data.draw.g;
|
||||
@@ -1164,6 +1320,8 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||
.mode = cmd->data.draw.blend,
|
||||
.shadeModel = GU_SMOOTH
|
||||
};
|
||||
SetDrawState(data);
|
||||
verts = PSP_GetVertTV(&data->drawstate, gpumem, cmd, 2 * count);
|
||||
PSP_SetBlendState(data, &state);
|
||||
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, 2 * count, 0, verts);
|
||||
break;
|
||||
@@ -1182,6 +1340,8 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||
.mode = cmd->data.draw.blend,
|
||||
.shadeModel = GU_SMOOTH
|
||||
};
|
||||
SetDrawState(data);
|
||||
verts = PSP_GetVertTV(&data->drawstate, gpumem, cmd, 4);
|
||||
PSP_SetBlendState(data, &state);
|
||||
sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, 4, 0, verts);
|
||||
break;
|
||||
@@ -1190,14 +1350,15 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||
case SDL_RENDERCMD_GEOMETRY:
|
||||
{
|
||||
const size_t count = cmd->data.draw.count;
|
||||
SetDrawState(data);
|
||||
if (!cmd->data.draw.texture) {
|
||||
const VertCV *verts = (VertCV *)(gpumem + cmd->data.draw.first);
|
||||
const VertCV *verts = PSP_GetVertCV(&data->drawstate, gpumem, cmd, count);
|
||||
sceGuDisable(GU_TEXTURE_2D);
|
||||
/* In GU_SMOOTH mode */
|
||||
sceGuDrawArray(GU_TRIANGLES, GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_2D, count, 0, verts);
|
||||
sceGuEnable(GU_TEXTURE_2D);
|
||||
} else {
|
||||
const VertTCV *verts = (VertTCV *)(gpumem + cmd->data.draw.first);
|
||||
const VertTCV *verts; /*= (VertTCV *)(gpumem + cmd->data.draw.first);*/
|
||||
const Uint8 a = cmd->data.draw.a;
|
||||
const Uint8 r = cmd->data.draw.r;
|
||||
const Uint8 g = cmd->data.draw.g;
|
||||
@@ -1208,6 +1369,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||
.mode = cmd->data.draw.blend,
|
||||
.shadeModel = GU_FLAT
|
||||
};
|
||||
verts = PSP_GetVertTCV(&data->drawstate, gpumem, cmd, count);
|
||||
TextureActivate(cmd->data.draw.texture);
|
||||
PSP_SetBlendState(data, &state);
|
||||
sceGuDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_2D, count, 0, verts);
|
||||
|
||||
+67
-2
@@ -412,6 +412,66 @@ static void BlitRGBtoRGBPixelAlphaMMX(SDL_BlitInfo *info)
|
||||
|
||||
#endif /* __MMX__ */
|
||||
|
||||
#if defined(__loongarch_sx)
|
||||
|
||||
static void
|
||||
BlitRGBtoRGBPixelAlphaLSX(SDL_BlitInfo * info)
|
||||
{
|
||||
int width = info->dst_w;
|
||||
int height = info->dst_h;
|
||||
Uint32 *srcp = (Uint32 *) info->src;
|
||||
int srcskip = info->src_skip >> 2;
|
||||
Uint32 *dstp = (Uint32 *) info->dst;
|
||||
int dstskip = info->dst_skip >> 2;
|
||||
SDL_PixelFormat *sf = info->src_fmt;
|
||||
Uint32 amask = sf->Amask;
|
||||
Uint32 ashift = sf->Ashift;
|
||||
Uint64 multmask, multmask2;
|
||||
|
||||
__m128i src1, src2, src3, dst1, alpha, alpha2;
|
||||
multmask = 0x00FF;
|
||||
multmask <<= (ashift * 2);
|
||||
multmask2 = 0x00FF00FF00FF00FFULL;
|
||||
|
||||
while (height--) {
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP4({
|
||||
Uint32 alpha1 = *srcp & amask;
|
||||
if (alpha1 == 0) {
|
||||
/* do nothing */
|
||||
} else if (alpha1 == amask) {
|
||||
*dstp = *srcp;
|
||||
} else {
|
||||
src1 = __lsx_vreplgr2vr_w(*srcp);
|
||||
src1 = __lsx_vinsgr2vr_w(src1, *dstp, 1);
|
||||
src2 = __lsx_vsllwil_hu_bu(src1, 0);
|
||||
|
||||
alpha = __lsx_vreplgr2vr_w(alpha1);
|
||||
alpha = __lsx_vsrl_d(alpha, __lsx_vreplgr2vr_d(ashift));
|
||||
alpha = __lsx_vilvl_h(alpha, alpha);
|
||||
alpha2 = __lsx_vilvl_w(alpha, alpha);
|
||||
alpha = __lsx_vor_v(alpha2, __lsx_vreplgr2vr_d(multmask));
|
||||
alpha2 = __lsx_vxor_v(alpha2, __lsx_vreplgr2vr_d(multmask2));
|
||||
|
||||
src3 = __lsx_vilvl_d(alpha2, alpha);
|
||||
src1 = __lsx_vmul_h(src2, src3);
|
||||
src1 = __lsx_vsrli_h(src1, 8);
|
||||
src2 = __lsx_vilvh_d(src1, src1);
|
||||
src1 = __lsx_vadd_h(src1, src2);
|
||||
dst1 = __lsx_vssrlni_bu_h(src1, src1, 0);
|
||||
__lsx_vstelm_w(dst1, dstp, 0, 0);
|
||||
}
|
||||
++srcp;
|
||||
++dstp;
|
||||
}, width);
|
||||
/* *INDENT-ON* */
|
||||
srcp += srcskip;
|
||||
dstp += dstskip;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __loongarch_sx */
|
||||
|
||||
#ifdef SDL_ARM_SIMD_BLITTERS
|
||||
void BlitARGBto565PixelAlphaARMSIMDAsm(int32_t w, int32_t h, uint16_t *dst, int32_t dst_stride, uint32_t *src, int32_t src_stride);
|
||||
|
||||
@@ -1456,7 +1516,7 @@ SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface)
|
||||
|
||||
case 4:
|
||||
if (sf->Rmask == df->Rmask && sf->Gmask == df->Gmask && sf->Bmask == df->Bmask && sf->BytesPerPixel == 4) {
|
||||
#if defined(__MMX__) || defined(__3dNOW__)
|
||||
#if defined(__MMX__) || defined(__3dNOW__) || defined(__loongarch_sx)
|
||||
if (sf->Rshift % 8 == 0 && sf->Gshift % 8 == 0 && sf->Bshift % 8 == 0 && sf->Ashift % 8 == 0 && sf->Aloss == 0) {
|
||||
#ifdef __3dNOW__
|
||||
if (SDL_Has3DNow()) {
|
||||
@@ -1467,9 +1527,14 @@ SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface)
|
||||
if (SDL_HasMMX()) {
|
||||
return BlitRGBtoRGBPixelAlphaMMX;
|
||||
}
|
||||
#endif
|
||||
#ifdef __loongarch_sx
|
||||
if (SDL_HasLSX()) {
|
||||
return BlitRGBtoRGBPixelAlphaLSX;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif /* __MMX__ || __3dNOW__ */
|
||||
#endif /* __MMX__ || __3dNOW__ || __loongarch_sx*/
|
||||
if (sf->Amask == 0xff000000) {
|
||||
#ifdef SDL_ARM_NEON_BLITTERS
|
||||
if (SDL_HasNEON()) {
|
||||
|
||||
@@ -1186,6 +1186,7 @@ EGLSurface *SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
|
||||
/* max 2 key+value pairs, plus terminator. */
|
||||
EGLint attribs[5];
|
||||
int attr = 0;
|
||||
int opaque_ext_idx = -1;
|
||||
|
||||
EGLSurface *surface;
|
||||
|
||||
@@ -1220,6 +1221,7 @@ EGLSurface *SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
|
||||
#ifdef EGL_EXT_present_opaque
|
||||
if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_EXT_present_opaque")) {
|
||||
const SDL_bool allow_transparent = SDL_GetHintBoolean(SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY, SDL_FALSE);
|
||||
opaque_ext_idx = attr;
|
||||
attribs[attr++] = EGL_PRESENT_OPAQUE_EXT;
|
||||
attribs[attr++] = allow_transparent ? EGL_FALSE : EGL_TRUE;
|
||||
}
|
||||
@@ -1231,6 +1233,16 @@ EGLSurface *SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
|
||||
_this->egl_data->egl_display,
|
||||
_this->egl_data->egl_config,
|
||||
nw, &attribs[0]);
|
||||
if (surface == EGL_NO_SURFACE) {
|
||||
/* we had a report of Nvidia drivers that report EGL_BAD_ATTRIBUTE if you try to
|
||||
* use EGL_PRESENT_OPAQUE_EXT, even when EGL_EXT_present_opaque is reported as available.
|
||||
* If we used it, try a second time without this attribute. */
|
||||
if ((_this->egl_data->eglGetError() == EGL_BAD_ATTRIBUTE) && (opaque_ext_idx >= 0)) {
|
||||
SDL_memmove(&attribs[opaque_ext_idx], &attribs[opaque_ext_idx + 2], sizeof (attribs[0]) * ((attr - opaque_ext_idx) - 2));
|
||||
surface = _this->egl_data->eglCreateWindowSurface(_this->egl_data->egl_display, _this->egl_data->egl_config, nw, &attribs[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (surface == EGL_NO_SURFACE) {
|
||||
SDL_EGL_SetError("unable to create an EGL window surface", "eglCreateWindowSurface");
|
||||
}
|
||||
|
||||
@@ -135,6 +135,61 @@ DEFINE_SSE_FILLRECT(4, Uint32)
|
||||
/* *INDENT-ON* */ /* clang-format on */
|
||||
#endif /* __SSE__ */
|
||||
|
||||
#if defined(__loongarch_sx)
|
||||
|
||||
#define LSX_BEGIN __m128i c128 = __lsx_vreplgr2vr_w(color);
|
||||
|
||||
#define LSX_WORK \
|
||||
for (i = n / 64; i--;) { \
|
||||
__lsx_vst(c128, p, 0); \
|
||||
__lsx_vst(c128, p, 16); \
|
||||
__lsx_vst(c128, p, 32); \
|
||||
__lsx_vst(c128, p, 48); \
|
||||
p += 64; \
|
||||
}
|
||||
|
||||
#define DEFINE_LSX_FILLRECT(bpp, type) \
|
||||
static void \
|
||||
SDL_FillRect##bpp##LSX(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \
|
||||
{ \
|
||||
int i, n; \
|
||||
Uint8 *p = NULL; \
|
||||
\
|
||||
LSX_BEGIN; \
|
||||
\
|
||||
while (h--) { \
|
||||
n = w * bpp; \
|
||||
p = pixels; \
|
||||
\
|
||||
if (n > 63) { \
|
||||
int adjust = 16 - ((uintptr_t)p & 15); \
|
||||
if (adjust < 16) { \
|
||||
n -= adjust; \
|
||||
adjust /= bpp; \
|
||||
while (adjust--) { \
|
||||
*((type *)p) = (type)color; \
|
||||
p += bpp; \
|
||||
} \
|
||||
} \
|
||||
LSX_WORK; \
|
||||
} \
|
||||
if (n & 63) { \
|
||||
int remainder = (n & 63); \
|
||||
remainder /= bpp; \
|
||||
while (remainder--) { \
|
||||
*((type *)p) = (type)color; \
|
||||
p += bpp; \
|
||||
} \
|
||||
} \
|
||||
pixels += pitch; \
|
||||
} \
|
||||
\
|
||||
}
|
||||
|
||||
DEFINE_LSX_FILLRECT(4, Uint32)
|
||||
|
||||
#endif
|
||||
|
||||
static void SDL_FillRect1(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
|
||||
{
|
||||
int n;
|
||||
@@ -423,6 +478,13 @@ int SDL_FillRects(SDL_Surface *dst, const SDL_Rect *rects, int count,
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __loongarch_sx
|
||||
if (SDL_HasLSX()) {
|
||||
fill_function = SDL_FillRect4LSX;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
fill_function = SDL_FillRect4;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -31,8 +31,6 @@ SDL_bool SDL_HASINTERSECTION(const RECTTYPE *A, const RECTTYPE *B)
|
||||
} else if (!B) {
|
||||
SDL_InvalidParamError("B");
|
||||
return SDL_FALSE;
|
||||
} else if (SDL_RECTEMPTY(A) || SDL_RECTEMPTY(B)) {
|
||||
return SDL_FALSE; /* Special cases for empty rects */
|
||||
}
|
||||
|
||||
/* Horizontal intersection */
|
||||
@@ -79,10 +77,6 @@ SDL_bool SDL_INTERSECTRECT(const RECTTYPE *A, const RECTTYPE *B, RECTTYPE *resul
|
||||
} else if (!result) {
|
||||
SDL_InvalidParamError("result");
|
||||
return SDL_FALSE;
|
||||
} else if (SDL_RECTEMPTY(A) || SDL_RECTEMPTY(B)) { /* Special cases for empty rects */
|
||||
result->w = 0;
|
||||
result->h = 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Horizontal intersection */
|
||||
|
||||
@@ -399,6 +399,7 @@ struct SDL_VideoDevice
|
||||
int no_error;
|
||||
int retained_backing;
|
||||
int driver_loaded;
|
||||
int HAS_GL_ARB_color_buffer_float;
|
||||
char driver_path[256];
|
||||
void *dll_handle;
|
||||
} gl_config;
|
||||
|
||||
@@ -70,6 +70,10 @@
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#ifndef GL_RGBA_FLOAT_MODE_ARB
|
||||
#define GL_RGBA_FLOAT_MODE_ARB 0x8820
|
||||
#endif /* GL_RGBA_FLOAT_MODE_ARB */
|
||||
|
||||
/* Available video drivers */
|
||||
static VideoBootStrap *bootstrap[] = {
|
||||
#ifdef SDL_VIDEO_DRIVER_COCOA
|
||||
@@ -4036,6 +4040,15 @@ int SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
|
||||
*value = _this->gl_config.no_error;
|
||||
return 0;
|
||||
}
|
||||
case SDL_GL_FLOATBUFFERS:
|
||||
{
|
||||
if (_this->gl_config.HAS_GL_ARB_color_buffer_float) {
|
||||
attrib = GL_RGBA_FLOAT_MODE_ARB;
|
||||
break;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
default:
|
||||
return SDL_SetError("Unknown OpenGL attribute");
|
||||
}
|
||||
|
||||
@@ -295,9 +295,11 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
|
||||
behaviour there. https://github.com/libsdl-org/SDL/issues/10340
|
||||
(13.6 still needs it, presumably 13.7 does, too.) */
|
||||
SDL_bool background_app_default = SDL_FALSE;
|
||||
#if _SDL_HAS_BUILTIN(__builtin_available)
|
||||
if (@available(macOS 14.0, *)) {
|
||||
background_app_default = SDL_TRUE; /* by default, don't explicitly activate the dock and then us again to force to foreground */
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!SDL_GetHintBoolean(SDL_HINT_MAC_BACKGROUND_APP, background_app_default)) {
|
||||
/* Get more aggressive for Catalina: activate the Dock first so we definitely reset all activation state. */
|
||||
|
||||
@@ -338,6 +338,7 @@ KMSDRM_FBInfo *KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo)
|
||||
unsigned w, h;
|
||||
int rc = -1;
|
||||
int num_planes = 0;
|
||||
int i;
|
||||
uint32_t format, strides[4] = { 0 }, handles[4] = { 0 }, offsets[4] = { 0 }, flags = 0;
|
||||
uint64_t modifiers[4] = { 0 };
|
||||
|
||||
@@ -374,7 +375,7 @@ KMSDRM_FBInfo *KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo)
|
||||
|
||||
modifiers[0] = KMSDRM_gbm_bo_get_modifier(bo);
|
||||
num_planes = KMSDRM_gbm_bo_get_plane_count(bo);
|
||||
for (int i = 0; i < num_planes; i++) {
|
||||
for (i = 0; i < num_planes; i++) {
|
||||
strides[i] = KMSDRM_gbm_bo_get_stride_for_plane(bo, i);
|
||||
handles[i] = KMSDRM_gbm_bo_get_handle_for_plane(bo, i).u32;
|
||||
offsets[i] = KMSDRM_gbm_bo_get_offset(bo, i);
|
||||
|
||||
@@ -2681,23 +2681,28 @@ static void relative_pointer_handle_relative_motion(void *data,
|
||||
struct SDL_WaylandInput *input = data;
|
||||
SDL_VideoData *d = input->display;
|
||||
SDL_WindowData *window = input->pointer_focus;
|
||||
double dx_unaccel;
|
||||
double dy_unaccel;
|
||||
double dx;
|
||||
double dy;
|
||||
double dx_mod;
|
||||
double dy_mod;
|
||||
|
||||
dx_unaccel = wl_fixed_to_double(dx_unaccel_w);
|
||||
dy_unaccel = wl_fixed_to_double(dy_unaccel_w);
|
||||
if (!d->relative_mode_accelerated) {
|
||||
dx = wl_fixed_to_double(dx_unaccel_w);
|
||||
dy = wl_fixed_to_double(dy_unaccel_w);
|
||||
} else {
|
||||
dx = wl_fixed_to_double(dx_w) * (window ? window->pointer_scale_x : 1.0);
|
||||
dy = wl_fixed_to_double(dy_w) * (window ? window->pointer_scale_y : 1.0);
|
||||
}
|
||||
|
||||
/* Add left over fraction from last event. */
|
||||
dx_unaccel += input->dx_frac;
|
||||
dy_unaccel += input->dy_frac;
|
||||
dx += input->dx_frac;
|
||||
dy += input->dy_frac;
|
||||
|
||||
input->dx_frac = modf(dx_unaccel, &dx);
|
||||
input->dy_frac = modf(dy_unaccel, &dy);
|
||||
input->dx_frac = modf(dx, &dx_mod);
|
||||
input->dy_frac = modf(dy, &dy_mod);
|
||||
|
||||
if (input->pointer_focus && d->relative_mouse_mode) {
|
||||
SDL_SendMouseMotion(window->sdlwindow, 0, 1, (int)dx, (int)dy);
|
||||
SDL_SendMouseMotion(window->sdlwindow, 0, 1, (int)dx_mod, (int)dy_mod);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -537,6 +537,9 @@ static int Wayland_SetRelativeMouseMode(SDL_bool enabled)
|
||||
SDL_VideoData *data = (SDL_VideoData *)vd->driverdata;
|
||||
|
||||
if (enabled) {
|
||||
/* Clients use relative warp mode to get accelerated motion deltas, which Wayland delivers internally. */
|
||||
data->relative_mode_accelerated = SDL_GetHintBoolean(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, SDL_FALSE);
|
||||
|
||||
/* Disable mouse warp emulation if it's enabled. */
|
||||
if (data->input->relative_mode_override) {
|
||||
data->input->relative_mode_override = SDL_FALSE;
|
||||
|
||||
@@ -101,6 +101,7 @@ typedef struct
|
||||
char *classname;
|
||||
|
||||
int relative_mouse_mode;
|
||||
int relative_mode_accelerated;
|
||||
SDL_bool egl_transparency_enabled;
|
||||
} SDL_VideoData;
|
||||
|
||||
|
||||
@@ -250,7 +250,10 @@ static void WIN_FreeCursor(SDL_Cursor *cursor)
|
||||
static int WIN_ShowCursor(SDL_Cursor *cursor)
|
||||
{
|
||||
if (!cursor) {
|
||||
cursor = SDL_blank_cursor;
|
||||
if (GetSystemMetrics(SM_REMOTESESSION)) {
|
||||
// Use a blank cursor so we continue to get relative motion over RDP
|
||||
cursor = SDL_blank_cursor;
|
||||
}
|
||||
}
|
||||
if (cursor) {
|
||||
SDL_cursor = (HCURSOR)cursor->driverdata;
|
||||
|
||||
@@ -511,6 +511,10 @@ void WIN_GL_InitExtensions(_THIS)
|
||||
_this->gl_data->HAS_WGL_ARB_create_context_no_error = SDL_TRUE;
|
||||
}
|
||||
|
||||
/* Check for WGL_ARB_pixel_format_float */
|
||||
_this->gl_data->HAS_WGL_ARB_pixel_format_float =
|
||||
HasExtension("WGL_ARB_pixel_format_float", extensions);
|
||||
|
||||
_this->gl_data->wglMakeCurrent(hdc, NULL);
|
||||
_this->gl_data->wglDeleteContext(hglrc);
|
||||
ReleaseDC(hwnd, hdc);
|
||||
@@ -641,7 +645,7 @@ static int WIN_GL_SetupWindowInternal(_THIS, SDL_Window *window)
|
||||
*iAttr++ = _this->gl_config.multisamplesamples;
|
||||
}
|
||||
|
||||
if (_this->gl_config.floatbuffers) {
|
||||
if (_this->gl_data->HAS_WGL_ARB_pixel_format_float && _this->gl_config.floatbuffers) {
|
||||
*iAttr++ = WGL_PIXEL_TYPE_ARB;
|
||||
*iAttr++ = WGL_TYPE_RGBA_FLOAT_ARB;
|
||||
}
|
||||
@@ -825,6 +829,9 @@ SDL_GLContext WIN_GL_CreateContext(_THIS, SDL_Window *window)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_this->gl_config.HAS_GL_ARB_color_buffer_float =
|
||||
SDL_GL_ExtensionSupported("GL_ARB_color_buffer_float");
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ struct SDL_GLDriverData
|
||||
SDL_bool HAS_WGL_ARB_context_flush_control;
|
||||
SDL_bool HAS_WGL_ARB_create_context_robustness;
|
||||
SDL_bool HAS_WGL_ARB_create_context_no_error;
|
||||
SDL_bool HAS_WGL_ARB_pixel_format_float;
|
||||
|
||||
/* Max version of OpenGL ES context that can be created if the
|
||||
implementation supports WGL_EXT_create_context_es2_profile.
|
||||
|
||||
@@ -67,6 +67,9 @@ static SDL_bool DriverIsProblematic(const char *driver)
|
||||
*/
|
||||
"dsp",
|
||||
|
||||
/* Jack isn't always configured properly on end user systems */
|
||||
"jack",
|
||||
|
||||
/* OpenBSD sound API. Can be used on Linux, but very rare. */
|
||||
"sndio",
|
||||
|
||||
|
||||
+83
-33
@@ -88,9 +88,19 @@ int hints_getHint(void *arg)
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
char *value;
|
||||
char *oldValue;
|
||||
} HintCallbackContext;
|
||||
|
||||
static void SDLCALL hints_testHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||
{
|
||||
*(char **)userdata = hint ? SDL_strdup(hint) : NULL;
|
||||
HintCallbackContext *context = userdata;
|
||||
|
||||
context->name = name ? SDL_strdup(name) : NULL;
|
||||
context->value = hint ? SDL_strdup(hint) : NULL;
|
||||
context->oldValue = oldValue ? SDL_strdup(oldValue) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,7 +112,7 @@ int hints_setHint(void *arg)
|
||||
const char *originalValue;
|
||||
char *value;
|
||||
const char *testValue;
|
||||
char *callbackValue;
|
||||
HintCallbackContext callback_data;
|
||||
SDL_bool result;
|
||||
int i, j;
|
||||
|
||||
@@ -152,8 +162,10 @@ int hints_setHint(void *arg)
|
||||
SDLTest_AssertPass("Call to SDL_GetHint() after saving and restoring hint");
|
||||
originalValue = SDL_GetHint(testHint);
|
||||
value = (originalValue == NULL) ? NULL : SDL_strdup(originalValue);
|
||||
SDL_SetHint(testHint, "temp");
|
||||
SDL_SetHint(testHint, value);
|
||||
result = SDL_SetHint(testHint, "temp");
|
||||
SDLTest_AssertCheck(!result, "SDL_SetHint(\"%s\", \"temp\") should return false", testHint);
|
||||
result = SDL_SetHint(testHint, value);
|
||||
SDLTest_AssertCheck(!result, "SDL_SetHint(\"%s\", \"%s\" should return false", testHint, value);
|
||||
SDL_free(value);
|
||||
testValue = SDL_GetHint(testHint);
|
||||
SDLTest_AssertCheck(
|
||||
@@ -162,15 +174,26 @@ int hints_setHint(void *arg)
|
||||
testValue);
|
||||
|
||||
SDLTest_AssertPass("Call to SDL_SetHintWithPriority(NULL, SDL_HINT_DEFAULT)");
|
||||
SDL_SetHintWithPriority(testHint, NULL, SDL_HINT_DEFAULT);
|
||||
result = SDL_SetHintWithPriority(testHint, NULL, SDL_HINT_DEFAULT);
|
||||
SDLTest_AssertCheck(!result, "SDL_SetHintWithPriority(\"%s\", NULL, SDL_HINT_DEFAULT) should return false", testHint);
|
||||
testValue = SDL_GetHint(testHint);
|
||||
SDLTest_AssertCheck(
|
||||
testValue && SDL_strcmp(testValue, "original") == 0,
|
||||
"testValue = %s, expected \"original\"",
|
||||
testValue);
|
||||
|
||||
SDLTest_AssertPass("Call to SDL_SetHint(\"\", \"data\")");
|
||||
result = SDL_SetHint("", "data");
|
||||
SDLTest_AssertCheck(result, "SDL_SetHint(\"\", \"data\") should return true");
|
||||
testValue = SDL_GetHint("");
|
||||
SDLTest_AssertCheck(
|
||||
testValue && SDL_strcmp(testValue, "data") == 0,
|
||||
"testValue = %s, expected \"data\"",
|
||||
testValue);
|
||||
|
||||
SDLTest_AssertPass("Call to SDL_SetHintWithPriority(\"temp\", SDL_HINT_OVERRIDE)");
|
||||
SDL_SetHintWithPriority(testHint, "temp", SDL_HINT_OVERRIDE);
|
||||
result = SDL_SetHintWithPriority(testHint, "temp", SDL_HINT_OVERRIDE);
|
||||
SDLTest_AssertCheck(result, "SDL_SetHintWithPriority(\"%s\", \"temp\", SDL_HINT_OVERRIDE) should return true", testHint);
|
||||
testValue = SDL_GetHint(testHint);
|
||||
SDLTest_AssertCheck(
|
||||
testValue && SDL_strcmp(testValue, "temp") == 0,
|
||||
@@ -178,7 +201,8 @@ int hints_setHint(void *arg)
|
||||
testValue);
|
||||
|
||||
SDLTest_AssertPass("Call to SDL_SetHintWithPriority(NULL, SDL_HINT_OVERRIDE)");
|
||||
SDL_SetHintWithPriority(testHint, NULL, SDL_HINT_OVERRIDE);
|
||||
result = SDL_SetHintWithPriority(testHint, NULL, SDL_HINT_OVERRIDE);
|
||||
SDLTest_AssertCheck(result, "SDL_SetHintWithPriority(\"%s\", NULL, SDL_HINT_OVERRIDE) should return true", testHint);
|
||||
testValue = SDL_GetHint(testHint);
|
||||
SDLTest_AssertCheck(
|
||||
testValue == NULL,
|
||||
@@ -194,49 +218,75 @@ int hints_setHint(void *arg)
|
||||
testValue);
|
||||
|
||||
/* Make sure callback functionality works past a reset */
|
||||
SDL_zero(callback_data);
|
||||
SDLTest_AssertPass("Call to SDL_AddHintCallback()");
|
||||
callbackValue = NULL;
|
||||
SDL_AddHintCallback(testHint, hints_testHintChanged, &callbackValue);
|
||||
SDL_AddHintCallback(testHint, hints_testHintChanged, &callback_data);
|
||||
SDLTest_AssertCheck(
|
||||
callbackValue && SDL_strcmp(callbackValue, "original") == 0,
|
||||
"callbackValue = %s, expected \"original\"",
|
||||
callbackValue);
|
||||
SDL_free(callbackValue);
|
||||
|
||||
SDLTest_AssertPass("Call to SDL_SetHintWithPriority(\"temp\", SDL_HINT_OVERRIDE), using callback");
|
||||
callbackValue = NULL;
|
||||
SDL_SetHintWithPriority(testHint, "temp", SDL_HINT_OVERRIDE);
|
||||
callback_data.name && SDL_strcmp(callback_data.name, testHint) == 0,
|
||||
"callback_data.name = \"%s\", expected \"%s\"",
|
||||
callback_data.name, testHint);
|
||||
SDLTest_AssertCheck(
|
||||
callbackValue && SDL_strcmp(callbackValue, "temp") == 0,
|
||||
"callbackValue = %s, expected \"temp\"",
|
||||
callbackValue);
|
||||
SDL_free(callbackValue);
|
||||
callback_data.value && SDL_strcmp(callback_data.value, "original") == 0,
|
||||
"callback_data.value = \"%s\", expected \"%s\"",
|
||||
callback_data.value, "original");
|
||||
SDL_free(callback_data.name);
|
||||
SDL_free(callback_data.value);
|
||||
SDL_free(callback_data.oldValue);
|
||||
|
||||
SDLTest_AssertPass("Call to SDL_ResetHint(), using callback");
|
||||
callbackValue = NULL;
|
||||
SDL_zero(callback_data);
|
||||
SDL_ResetHint(testHint);
|
||||
SDLTest_AssertCheck(
|
||||
callbackValue && SDL_strcmp(callbackValue, "original") == 0,
|
||||
callback_data.value && SDL_strcmp(callback_data.value, "original") == 0,
|
||||
"callbackValue = %s, expected \"original\"",
|
||||
callbackValue);
|
||||
callback_data.value);
|
||||
SDL_free(callback_data.name);
|
||||
SDL_free(callback_data.value);
|
||||
SDL_free(callback_data.oldValue);
|
||||
|
||||
SDLTest_AssertPass("Call to SDL_SetHintWithPriority(\"temp\", SDL_HINT_OVERRIDE), using callback after reset");
|
||||
callbackValue = NULL;
|
||||
SDL_SetHintWithPriority(testHint, "temp", SDL_HINT_OVERRIDE);
|
||||
SDL_zero(callback_data);
|
||||
result = SDL_SetHintWithPriority(testHint, "temp", SDL_HINT_OVERRIDE);
|
||||
SDLTest_AssertCheck(result, "SDL_SetHintWithPriority(\"%s\", \"temp\", SDL_HINT_OVERRIDE) should return true", testHint);
|
||||
SDLTest_AssertCheck(
|
||||
callbackValue && SDL_strcmp(callbackValue, "temp") == 0,
|
||||
callback_data.value && SDL_strcmp(callback_data.value, "temp") == 0,
|
||||
"callbackValue = %s, expected \"temp\"",
|
||||
callbackValue);
|
||||
SDL_free(callbackValue);
|
||||
callback_data.value);
|
||||
SDL_free(callback_data.name);
|
||||
SDL_free(callback_data.value);
|
||||
SDL_free(callback_data.oldValue);
|
||||
|
||||
SDLTest_AssertPass("Call to SDL_ResetHint(), after clearing callback");
|
||||
callbackValue = NULL;
|
||||
SDL_DelHintCallback(testHint, hints_testHintChanged, &callbackValue);
|
||||
SDL_zero(callback_data);
|
||||
SDL_DelHintCallback(testHint, hints_testHintChanged, &callback_data);
|
||||
SDL_ResetHint(testHint);
|
||||
SDLTest_AssertCheck(
|
||||
callbackValue == NULL,
|
||||
!callback_data.value,
|
||||
"callbackValue = %s, expected \"(null)\"",
|
||||
callbackValue);
|
||||
callback_data.value);
|
||||
SDL_free(callback_data.name);
|
||||
SDL_free(callback_data.value);
|
||||
SDL_free(callback_data.oldValue);
|
||||
|
||||
/* Make sure callback functionality work with hint renamed in sdl3 */
|
||||
SDLTest_AssertPass("Call to SDL_AddHintCallback()");
|
||||
SDL_AddHintCallback(SDL_HINT_ALLOW_TOPMOST, hints_testHintChanged, &callback_data);
|
||||
SDLTest_AssertPass("Call to SDL_SetHintWithPriority(\"temp\", SDL_HINT_OVERRIDE), using callback");
|
||||
SDL_zero(callback_data);
|
||||
result = SDL_SetHintWithPriority(SDL_HINT_ALLOW_TOPMOST, "temp", SDL_HINT_OVERRIDE);
|
||||
SDLTest_AssertCheck(result, "SDL_SetHintWithPriority(\"%s\", \"temp\", SDL_HINT_OVERRIDE) should return true", testHint);
|
||||
SDLTest_AssertCheck(
|
||||
callback_data.name && SDL_strcmp(callback_data.name, SDL_HINT_ALLOW_TOPMOST) == 0,
|
||||
"callback_data.name = \"%s\", expected \"%s\"",
|
||||
callback_data.name, SDL_HINT_ALLOW_TOPMOST);
|
||||
SDLTest_AssertCheck(
|
||||
callback_data.value && SDL_strcmp(callback_data.value, "temp") == 0,
|
||||
"callback_data.value = \"%s\", expected \"%s\"",
|
||||
callback_data.value, "temp");
|
||||
SDL_free(callback_data.name);
|
||||
SDL_free(callback_data.value);
|
||||
SDL_free(callback_data.oldValue);
|
||||
SDL_ResetHint(testHint);
|
||||
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
+279
-6
@@ -12,6 +12,38 @@
|
||||
|
||||
/* Helper functions */
|
||||
|
||||
/* !
|
||||
* \brief Private helper to check SDL_FRect equality
|
||||
*/
|
||||
static SDL_bool IsFRectEqual(const SDL_FRect *r1, const SDL_FRect *r2) {
|
||||
static const float MAX_DELTA = 1e-5f;
|
||||
SDL_FRect delta;
|
||||
delta.x = r1->x - r2->x;
|
||||
delta.y = r1->y - r2->y;
|
||||
delta.w = r1->w - r2->w;
|
||||
delta.h = r1->h - r2->h;
|
||||
|
||||
return -MAX_DELTA <= delta.x && delta.x <= MAX_DELTA
|
||||
&& -MAX_DELTA <= delta.y && delta.y <= MAX_DELTA
|
||||
&& -MAX_DELTA <= delta.w && delta.w <= MAX_DELTA
|
||||
&& -MAX_DELTA <= delta.w && delta.h <= MAX_DELTA;
|
||||
}
|
||||
|
||||
/* !
|
||||
* \brief Private helper to check SDL_FPoint equality
|
||||
*/
|
||||
static SDL_bool IsFPointEqual(const SDL_FPoint *p1, const SDL_FPoint *p2) {
|
||||
static const float MAX_DELTA = 1e-5f;
|
||||
SDL_FPoint delta;
|
||||
delta.x = p1->x - p2->x;
|
||||
delta.y = p1->y - p2->y;
|
||||
|
||||
return -MAX_DELTA <= delta.x && delta.x <= MAX_DELTA
|
||||
&& -MAX_DELTA <= delta.y && delta.y <= MAX_DELTA;
|
||||
}
|
||||
|
||||
/* Helper functions */
|
||||
|
||||
/* !
|
||||
* \brief Private helper to check SDL_IntersectRectAndLine results
|
||||
*/
|
||||
@@ -701,8 +733,8 @@ int rect_testIntersectRectEmpty(void *arg)
|
||||
*/
|
||||
int rect_testIntersectRectParam(void *arg)
|
||||
{
|
||||
SDL_Rect rectA;
|
||||
SDL_Rect rectB = { 0 };
|
||||
const SDL_Rect rectA = { 0, 0, 32, 32 };
|
||||
const SDL_Rect rectB = { 0, 0, 32, 32 };
|
||||
SDL_Rect result;
|
||||
SDL_bool intersection;
|
||||
|
||||
@@ -956,8 +988,8 @@ int rect_testHasIntersectionEmpty(void *arg)
|
||||
*/
|
||||
int rect_testHasIntersectionParam(void *arg)
|
||||
{
|
||||
SDL_Rect rectA;
|
||||
SDL_Rect rectB = { 0 };
|
||||
const SDL_Rect rectA = { 0, 0, 32, 32 };
|
||||
const SDL_Rect rectB = { 0, 0, 32, 32 };
|
||||
SDL_bool intersection;
|
||||
|
||||
/* invalid parameter combinations */
|
||||
@@ -1492,7 +1524,8 @@ int rect_testUnionRectInside(void *arg)
|
||||
*/
|
||||
int rect_testUnionRectParam(void *arg)
|
||||
{
|
||||
SDL_Rect rectA, rectB = { 0 };
|
||||
const SDL_Rect rectA = { 0, 0, 32, 32 };
|
||||
const SDL_Rect rectB = { 0, 0, 32, 32 };
|
||||
SDL_Rect result;
|
||||
|
||||
/* invalid parameter combinations */
|
||||
@@ -1698,6 +1731,226 @@ int rect_testFRectEqualsParam(void *arg)
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
/* !
|
||||
* \brief Test SDL_HasIntersectionF
|
||||
*
|
||||
* \sa
|
||||
* http://wiki.libsdl.org/SDL2/SDL_HasIntersectionF
|
||||
*/
|
||||
int rect_testHasIntersectionF(void *arg)
|
||||
{
|
||||
const struct {
|
||||
SDL_FRect r1;
|
||||
SDL_FRect r2;
|
||||
SDL_bool expected;
|
||||
} cases[] = {
|
||||
{ { 0, 0, 0, 0 }, {0, 0, 0, 0}, SDL_FALSE },
|
||||
{ { 0, 0, -200, 200 }, {0, 0, -200, 200}, SDL_FALSE },
|
||||
{ { 0, 0, 10, 10 }, {-5, 5, 10, 2}, SDL_TRUE },
|
||||
{ { 0, 0, 10, 10 }, {-5, -5, 10, 2}, SDL_FALSE },
|
||||
{ { 0, 0, 10, 10 }, {-5, -5, 2, 10}, SDL_FALSE },
|
||||
{ { 0, 0, 10, 10 }, {-5, -5, 5, 5}, SDL_FALSE },
|
||||
{ { 0, 0, 10, 10 }, {-5, -5, 5.1f, 5.1f}, SDL_TRUE },
|
||||
{ { 0, 0, 10, 10 }, {-4.99f, -4.99f, 5, 5}, SDL_TRUE },
|
||||
};
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < SDL_arraysize(cases); i++) {
|
||||
SDL_bool result;
|
||||
SDLTest_AssertPass("About to call SDL_HasIntersectionF(&{ %g, %g, %g, %g }, &{ %g, %g, %g, %g })",
|
||||
cases[i].r1.x, cases[i].r1.y, cases[i].r1.w, cases[i].r1.h,
|
||||
cases[i].r2.x, cases[i].r2.y, cases[i].r2.w, cases[i].r2.h
|
||||
);
|
||||
result = SDL_HasIntersectionF(&cases[i].r1, &cases[i].r2);
|
||||
SDLTest_AssertCheck(result == cases[i].expected, "Got %d, expected %d", result, cases[i].expected);
|
||||
}
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
/* !
|
||||
* \brief Test SDL_IntersectFRect
|
||||
*
|
||||
* \sa
|
||||
* http://wiki.libsdl.org/SDL2/SDL_IntersectFRect
|
||||
*/
|
||||
int rect_testIntersectFRect(void *arg)
|
||||
{
|
||||
const struct {
|
||||
SDL_FRect r1;
|
||||
SDL_FRect r2;
|
||||
SDL_bool result;
|
||||
SDL_FRect intersect;
|
||||
} cases[] = {
|
||||
{ { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, SDL_FALSE },
|
||||
{ { 0, 0, -200, 200 }, { 0, 0, -200, 200 }, SDL_FALSE },
|
||||
{ { 0, 0, 10, 10 }, { -5, 5, 9.9f, 2 }, SDL_TRUE, { 0, 5, 4.9f, 2 } },
|
||||
{ { 0, 0, 10, 10 }, { -5, -5, 10, 2 }, SDL_FALSE},
|
||||
{ { 0, 0, 10, 10 }, { -5, -5, 2, 10 }, SDL_FALSE},
|
||||
{ { 0, 0, 10, 10 }, { -5, -5, 5, 5 }, SDL_FALSE},
|
||||
{ { 0, 0, 10, 10 }, { -5, -5, 5.5f, 6 }, SDL_TRUE, { 0, 0, 0.5f, 1 } }
|
||||
};
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < SDL_arraysize(cases); i++) {
|
||||
SDL_bool result;
|
||||
SDL_FRect intersect;
|
||||
SDLTest_AssertPass("About to call SDL_IntersectFRect(&{ %g, %g, %g, %g }, &{ %g, %g, %g, %g })",
|
||||
cases[i].r1.x, cases[i].r1.y, cases[i].r1.w, cases[i].r1.h,
|
||||
cases[i].r2.x, cases[i].r2.y, cases[i].r2.w, cases[i].r2.h
|
||||
);
|
||||
result = SDL_IntersectFRect(&cases[i].r1, &cases[i].r2, &intersect);
|
||||
SDLTest_AssertCheck(result == cases[i].result, "Got %d, expected %d", result, cases[i].result);
|
||||
if (cases[i].result) {
|
||||
SDLTest_AssertCheck(IsFRectEqual(&intersect, &cases[i].intersect),
|
||||
"Got { %g, %g, %g, %g }, expected { %g, %g, %g, %g }",
|
||||
intersect.x, intersect.y, intersect.w, intersect.h,
|
||||
cases[i].intersect.x, cases[i].intersect.y, cases[i].intersect.w, cases[i].intersect.h);
|
||||
}
|
||||
}
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
/* !
|
||||
* \brief Test SDL_UnionFRect
|
||||
*
|
||||
* \sa
|
||||
* http://wiki.libsdl.org/SDL2/SDL_UnionFRect
|
||||
*/
|
||||
int rect_testUnionFRect(void *arg)
|
||||
{
|
||||
const struct {
|
||||
SDL_FRect r1;
|
||||
SDL_FRect r2;
|
||||
SDL_FRect expected;
|
||||
} cases[] = {
|
||||
{ { 0, 0, 10, 10 }, { 19.9f, 20, 10, 10 }, { 0, 0, 29.9f, 30 } },
|
||||
{ { 0, 0, 0, 0 }, { 20, 20.1f, 10.1f, 10 }, { 20, 20.1f, 10.1f, 10 } },
|
||||
{ { -200, -4.5f, 450, 33 }, { 20, 20, 10, 10 }, { -200, -4.5f, 450, 34.5f } },
|
||||
{ { 0, 0, 15, 16.5f }, { 20, 20, 0, 0 }, { 0, 0, 15, 16.5f } }
|
||||
};
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < SDL_arraysize(cases); i++) {
|
||||
SDL_FRect result;
|
||||
SDLTest_AssertPass("About to call SDL_UnionFRect(&{ %g, %g, %g, %g }, &{ %g, %g, %g, %g })",
|
||||
cases[i].r1.x, cases[i].r1.y, cases[i].r1.w, cases[i].r1.h,
|
||||
cases[i].r2.x, cases[i].r2.y, cases[i].r2.w, cases[i].r2.h
|
||||
);
|
||||
SDL_UnionFRect(&cases[i].r1, &cases[i].r2, &result);
|
||||
SDLTest_AssertCheck(IsFRectEqual(&result, &cases[i].expected),
|
||||
"Got { %g, %g, %g, %g }, expected { %g, %g, %g, %g }",
|
||||
result.x, result.y, result.w, result.h,
|
||||
cases[i].expected.x, cases[i].expected.y, cases[i].expected.w, cases[i].expected.h);
|
||||
}
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
/* !
|
||||
* \brief Test SDL_EncloseFPointsUnionFRect
|
||||
*
|
||||
* \sa
|
||||
* http://wiki.libsdl.org/SDL2/SDL_EncloseFPoints
|
||||
*/
|
||||
int rect_testEncloseFPoints(void *arg)
|
||||
{
|
||||
const struct {
|
||||
SDL_bool with_clip;
|
||||
SDL_FRect clip;
|
||||
SDL_bool result;
|
||||
SDL_FRect enclosing;
|
||||
} cases[] = {
|
||||
{ SDL_TRUE, { 0, 0, 10, 10 }, SDL_TRUE, { 0.5f, 0.1f, 6, 8 }},
|
||||
{ SDL_TRUE, { 1.2f, 1, 10, 10 }, SDL_TRUE, { 1.5f, 1.1f, 5, 7 }},
|
||||
{ SDL_TRUE, { -10, -10, 3, 3 }, SDL_FALSE },
|
||||
{ SDL_FALSE, { 0 }, SDL_TRUE, { 0.5, 0.1f, 6, 8 }}
|
||||
};
|
||||
const SDL_FPoint points[] = {
|
||||
{ 0.5f, 0.1f },
|
||||
{ 5.5f, 7.1f },
|
||||
{ 1.5f, 1.1f }
|
||||
};
|
||||
char points_str[256];
|
||||
size_t i;
|
||||
|
||||
SDL_strlcpy(points_str, "{", sizeof(points_str));
|
||||
for (i = 0; i < SDL_arraysize(points); i++) {
|
||||
char point_str[32];
|
||||
SDL_snprintf(point_str, sizeof(point_str), "{ %g, %g }, ", points[i].x, points[i].y);
|
||||
SDL_strlcat(points_str, point_str, sizeof(points_str));
|
||||
}
|
||||
SDL_strlcat(points_str, "}", sizeof(points_str));
|
||||
for (i = 0; i < SDL_arraysize(cases); i++) {
|
||||
char clip_str[64];
|
||||
SDL_bool result;
|
||||
SDL_FRect enclosing;
|
||||
const SDL_FRect* clip_ptr = NULL;
|
||||
if (cases[i].with_clip) {
|
||||
SDL_snprintf(clip_str, sizeof(clip_str), "&{ %g, %g, %g, %g }",
|
||||
cases[i].clip.x, cases[i].clip.y, cases[i].clip.w, cases[i].clip.h);
|
||||
clip_ptr = &cases[i].clip;
|
||||
} else {
|
||||
SDL_strlcpy(clip_str, "NULL", sizeof(clip_str));
|
||||
}
|
||||
SDLTest_AssertPass("About to call SDL_EncloseFPoints(&%s, %d, %s)", points_str, (int)SDL_arraysize(points), clip_str);
|
||||
result = SDL_EncloseFPoints(points, SDL_arraysize(points), clip_ptr, &enclosing);
|
||||
SDLTest_AssertCheck(result == cases[i].result, "Got %d, expected %d", result, cases[i].result);
|
||||
if (cases[i].result) {
|
||||
SDLTest_AssertCheck(IsFRectEqual(&enclosing, &cases[i].enclosing),
|
||||
"Got { %g, %g, %g, %g }, expected { %g, %g, %g, %g }",
|
||||
enclosing.x, enclosing.y, enclosing.w, enclosing.h,
|
||||
cases[i].enclosing.x, cases[i].enclosing.y, cases[i].enclosing.w, cases[i].enclosing.h);
|
||||
}
|
||||
}
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
/* !
|
||||
* \brief Test SDL_IntersectFRectAndLine
|
||||
*
|
||||
* \sa
|
||||
* http://wiki.libsdl.org/SDL2/SDL_IntersectFRectAndLine
|
||||
*/
|
||||
int rect_testIntersectFRectAndLine(void *arg)
|
||||
{
|
||||
const struct {
|
||||
SDL_FRect rect;
|
||||
SDL_FPoint p1;
|
||||
SDL_FPoint p2;
|
||||
SDL_bool result;
|
||||
SDL_FPoint expected1;
|
||||
SDL_FPoint expected2;
|
||||
} cases[] = {
|
||||
{ { 0, 0, 0, 0 }, { -4.8f, -4.8f }, { 5.2f, 5.2f }, SDL_FALSE },
|
||||
{ { 0, 0, 2, 2 }, { -1, -1 }, { 3.5f, 3.5f }, SDL_TRUE, { 0, 0 }, { 1, 1 } },
|
||||
{ { -4, -4, 14, 14 }, { 8, 22 }, { 8, 33}, SDL_FALSE }
|
||||
|
||||
};
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < SDL_arraysize(cases); i++) {
|
||||
SDL_bool result;
|
||||
SDL_FPoint p1 = cases[i].p1;
|
||||
SDL_FPoint p2 = cases[i].p2;
|
||||
|
||||
SDLTest_AssertPass("About to call SDL_IntersectFRectAndLine(&{%g, %g, %g, %g}, &%g, &%g, &%g, &%g)",
|
||||
cases[i].rect.x, cases[i].rect.y, cases[i].rect.w, cases[i].rect.h,
|
||||
p1.x, p1.y, p2.x, p2.y);
|
||||
result = SDL_IntersectFRectAndLine(&cases[i].rect, &p1.x, &p1.y, &p2.x, &p2.y);
|
||||
SDLTest_AssertCheck(result == cases[i].result, "Got %d, expected %d", result, cases[i].result);
|
||||
if (cases[i].result) {
|
||||
SDLTest_AssertCheck(IsFPointEqual(&p1, &cases[i].expected1),
|
||||
"Got p1={ %g, %g }, expected p1={ %g, %g }",
|
||||
p1.x, p1.y,
|
||||
cases[i].expected1.x, cases[i].expected1.y);
|
||||
SDLTest_AssertCheck(IsFPointEqual(&p2, &cases[i].expected2),
|
||||
"Got p2={ %g, %g }, expected p2={ %g, %g }",
|
||||
p2.x, p2.y,
|
||||
cases[i].expected2.x, cases[i].expected2.y);
|
||||
}
|
||||
}
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
/* ================= Test References ================== */
|
||||
|
||||
/* Rect test cases */
|
||||
@@ -1836,6 +2089,26 @@ static const SDLTest_TestCaseReference rectTest31 = {
|
||||
(SDLTest_TestCaseFp)rect_testFRectEqualsParam, "rect_testFRectEqualsParam", "Negative tests against SDL_FRectEquals with invalid parameters", TEST_ENABLED
|
||||
};
|
||||
|
||||
static const SDLTest_TestCaseReference rectTest32 = {
|
||||
(SDLTest_TestCaseFp)rect_testHasIntersectionF, "rect_testHasIntersectionF", "Tests SDL_HasIntersectionF", TEST_ENABLED
|
||||
};
|
||||
|
||||
static const SDLTest_TestCaseReference rectTest33 = {
|
||||
(SDLTest_TestCaseFp)rect_testIntersectFRect, "rect_testIntersectFRect", "Tests SDL_IntersectFRect", TEST_ENABLED
|
||||
};
|
||||
|
||||
static const SDLTest_TestCaseReference rectTest34 = {
|
||||
(SDLTest_TestCaseFp)rect_testUnionFRect, "rect_testUnionFRect", "Tests SDL_UnionFRect", TEST_ENABLED
|
||||
};
|
||||
|
||||
static const SDLTest_TestCaseReference rectTest35 = {
|
||||
(SDLTest_TestCaseFp)rect_testEncloseFPoints, "rect_testEncloseFPoints", "Tests SDL_EncloseFPoints", TEST_ENABLED
|
||||
};
|
||||
|
||||
static const SDLTest_TestCaseReference rectTest36 = {
|
||||
(SDLTest_TestCaseFp)rect_testIntersectFRectAndLine, "rect_testIntersectFRectAndLine", "Tests SDL_IntersectFRectAndLine", TEST_ENABLED
|
||||
};
|
||||
|
||||
/* !
|
||||
* \brief Sequence of Rect test cases; functions that handle simple rectangles including overlaps and merges.
|
||||
*
|
||||
@@ -1845,7 +2118,7 @@ static const SDLTest_TestCaseReference rectTest31 = {
|
||||
static const SDLTest_TestCaseReference *rectTests[] = {
|
||||
&rectTest1, &rectTest2, &rectTest3, &rectTest4, &rectTest5, &rectTest6, &rectTest7, &rectTest8, &rectTest9, &rectTest10, &rectTest11, &rectTest12, &rectTest13, &rectTest14,
|
||||
&rectTest15, &rectTest16, &rectTest17, &rectTest18, &rectTest19, &rectTest20, &rectTest21, &rectTest22, &rectTest23, &rectTest24, &rectTest25, &rectTest26, &rectTest27,
|
||||
&rectTest28, &rectTest29, &rectTest30, &rectTest31, NULL
|
||||
&rectTest28, &rectTest29, &rectTest30, &rectTest31, &rectTest32, &rectTest33, &rectTest34, &rectTest35, &rectTest36, NULL
|
||||
};
|
||||
|
||||
/* Rect test suite (global) */
|
||||
|
||||
@@ -811,6 +811,136 @@ int render_testBlitBlend(void *arg)
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
static Uint32 read_surface_pixel32(SDL_Surface *surface, int x, int y) {
|
||||
Uint32 result;
|
||||
|
||||
if (x >= surface->w || y >= surface->h) {
|
||||
SDLTest_AssertCheck(x < surface->w, "x (%d) < surface->w (%d)", x, surface->w);
|
||||
SDLTest_AssertCheck(y < surface->h, "y (%d) < surface->h (%d)", y, surface->h);
|
||||
result = 0xdeadbabe;
|
||||
} else {
|
||||
SDL_memcpy(&result, (Uint8 *)surface->pixels + surface->pitch * y + surface->format->BytesPerPixel * x, sizeof(Uint32));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int render_testRGBSurfaceNoAlpha(void* arg)
|
||||
{
|
||||
SDL_Surface *surface;
|
||||
SDL_Renderer *software_renderer;
|
||||
SDL_Surface *surface2;
|
||||
SDL_Texture *texture2;
|
||||
int result;
|
||||
SDL_Rect dest_rect;
|
||||
SDL_Point point;
|
||||
Uint32 pixel;
|
||||
|
||||
SDLTest_AssertPass("About to call SDL_CreateRGBSurface(0, 128, 128, 32, 0xff0000, 0xff00, 0xff, 0)");
|
||||
surface = SDL_CreateRGBSurface(0, 128, 128, 32, 0xff0000, 0xff00, 0xff, 0);
|
||||
SDLTest_AssertCheck(surface != NULL, "Returned surface must be not NULL");
|
||||
|
||||
SDLTest_AssertCheck(surface->format->BitsPerPixel == 32, "surface->format->BitsPerPixel should be 32, actual value is %d", surface->format->BitsPerPixel);
|
||||
SDLTest_AssertCheck(surface->format->BytesPerPixel == 4, "surface->format->BytesPerPixels should be 4, actual value is %d", surface->format->BytesPerPixel);
|
||||
|
||||
SDLTest_AssertPass("About to call SDL_CreateSoftwareRenderer(surface)");
|
||||
software_renderer = SDL_CreateSoftwareRenderer(surface);
|
||||
SDLTest_AssertCheck(software_renderer != NULL, "Returned renderer must be not NULL");
|
||||
|
||||
SDLTest_AssertPass("About to call SDL_CreateRGBSurface(0, 16, 16, 32, 0xff0000, 0xff00, 0xff, 0)");
|
||||
surface2 = SDL_CreateRGBSurface(0, 16, 16, 32, 0xff0000, 0xff00, 0xff, 0);
|
||||
SDLTest_AssertCheck(surface2 != NULL, "Returned surface must be not NULL");
|
||||
|
||||
SDLTest_AssertPass("About to call SDL_FillRect(surface2, NULL, 0)");
|
||||
result = SDL_FillRect(surface2, NULL, SDL_MapRGB(surface2->format, 0, 0, 0));
|
||||
SDLTest_AssertCheck(result == 0, "Result should be 0, actual value is %d", result);
|
||||
|
||||
SDLTest_AssertPass("About to call SDL_CreateTextureFromSurface(software_renderer, surface2)");
|
||||
texture2 = SDL_CreateTextureFromSurface(software_renderer, surface2);
|
||||
SDLTest_AssertCheck(texture2 != NULL, "Returned texture is not NULL");
|
||||
|
||||
SDLTest_AssertPass("About to call SDL_SetRenderDrawColor(renderer, 0xaa, 0xbb, 0xcc, 0x0)");
|
||||
result = SDL_SetRenderDrawColor(software_renderer, 0xaa, 0xbb, 0xcc, 0x0);
|
||||
|
||||
SDLTest_AssertPass("About to call SDL_RenderClear(renderer)");
|
||||
result = SDL_RenderClear(software_renderer);
|
||||
SDLTest_AssertCheck(result == 0, "Result should be 0, actual value is %d", result);
|
||||
|
||||
SDLTest_AssertPass("About to call SDL_SetRenderDrawColor(renderer, 0x0, 0x0, 0x0, 0x0)");
|
||||
result = SDL_SetRenderDrawColor(software_renderer, 0x0, 0x0, 0x0, 0x0);
|
||||
SDLTest_AssertCheck(result == 0, "Result should be 0, actual value is %d", result);
|
||||
|
||||
dest_rect.x = 32;
|
||||
dest_rect.y = 32;
|
||||
dest_rect.w = surface2->w;
|
||||
dest_rect.h = surface2->h;
|
||||
point.x = 0;
|
||||
point.y = 0;
|
||||
SDLTest_AssertPass("About to call SDL_RenderCopy(software_renderer, texture, NULL, &{%d, %d, %d, %d})",
|
||||
dest_rect.x, dest_rect.h, dest_rect.w, dest_rect.h);
|
||||
result = SDL_RenderCopyEx(software_renderer, texture2, NULL, &dest_rect, 180, &point, SDL_FLIP_NONE);
|
||||
SDLTest_AssertCheck(result == 0, "Result should be 0, actual value is %d", result);
|
||||
|
||||
SDLTest_AssertPass("About to call SDL_RenderPresent(software_renderer)");
|
||||
SDL_RenderPresent(software_renderer);
|
||||
|
||||
pixel = read_surface_pixel32(surface, 0, 0);
|
||||
SDLTest_AssertCheck(pixel == 0xAABBCCu, "Pixel at (0, 0) should be 0x%08x, actual value is 0x%08" SDL_PRIx32, 0xAABBCCu, pixel);
|
||||
pixel = read_surface_pixel32(surface, 15, 15);
|
||||
SDLTest_AssertCheck(pixel == 0xAABBCCu, "Pixel at (15, 15) should be 0x%08x, actual value is 0x%08" SDL_PRIx32, 0xAABBCCu, pixel);
|
||||
pixel = read_surface_pixel32(surface, 16, 16);
|
||||
SDLTest_AssertCheck(pixel == 0xFF000000u, "Pixel at (16, 16) should be 0x%08x, actual value is 0x%08" SDL_PRIx32, 0xFF000000u, pixel);
|
||||
pixel = read_surface_pixel32(surface, 31, 31);
|
||||
SDLTest_AssertCheck(pixel == 0xFF000000u, "Pixel at (31, 31) should be 0x%08x, actual value is 0x%08" SDL_PRIx32, 0xFF000000u, pixel);
|
||||
pixel = read_surface_pixel32(surface, 32, 32);
|
||||
SDLTest_AssertCheck(pixel == 0xAABBCCu, "Pixel at (32, 32) should be 0x%08x, actual value is 0x%08" SDL_PRIx32, 0xAABBCCu, pixel);
|
||||
|
||||
SDL_DestroyTexture(texture2);
|
||||
SDL_FreeSurface(surface2);
|
||||
SDL_DestroyRenderer(software_renderer);
|
||||
SDL_FreeSurface(surface);
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tests setting and getting texture scale mode.
|
||||
*
|
||||
* \sa
|
||||
* http://wiki.libsdl.org/SDL2/SDL_SetTextureScaleMode
|
||||
* http://wiki.libsdl.org/SDL2/SDL_GetTextureScaleMode
|
||||
*/
|
||||
int render_testGetSetTextureScaleMode(void *arg)
|
||||
{
|
||||
const struct {
|
||||
const char *name;
|
||||
SDL_ScaleMode mode;
|
||||
} modes[] = {
|
||||
{ "SDL_ScaleModeNearest", SDL_ScaleModeNearest },
|
||||
{ "SDL_ScaleModeLinear", SDL_ScaleModeLinear },
|
||||
{ "SDL_ScaleModeBest", SDL_ScaleModeBest }
|
||||
};
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < SDL_arraysize(modes); i++) {
|
||||
SDL_Texture *texture;
|
||||
int result;
|
||||
SDL_ScaleMode actual_mode = SDL_ScaleModeNearest;
|
||||
|
||||
SDL_ClearError();
|
||||
SDLTest_AssertPass("About to call SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 16, 16)");
|
||||
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 16, 16);
|
||||
SDLTest_AssertCheck(texture != NULL, "SDL_CreateTexture must return a non-NULL texture");
|
||||
SDLTest_AssertPass("About to call SDL_SetTextureScaleMode(texture, %s)", modes[i].name);
|
||||
result = SDL_SetTextureScaleMode(texture, modes[i].mode);
|
||||
SDLTest_AssertCheck(result == 0, "SDL_SetTextureScaleMode must return 0, actual %d", result);
|
||||
SDLTest_AssertPass("About to call SDL_GetTextureScaleMode(texture)");
|
||||
result = SDL_GetTextureScaleMode(texture, &actual_mode);
|
||||
SDLTest_AssertCheck(result == 0, "SDL_SetTextureScaleMode must return 0, actual %d", result);
|
||||
SDLTest_AssertCheck(actual_mode == modes[i].mode, "SDL_GetTextureScaleMode must return %s (%d), actual=%d",
|
||||
modes[i].name, modes[i].mode, actual_mode);
|
||||
}
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks to see if functionality is supported. Helper function.
|
||||
*/
|
||||
@@ -1161,9 +1291,17 @@ static const SDLTest_TestCaseReference renderTest7 = {
|
||||
(SDLTest_TestCaseFp)render_testBlitBlend, "render_testBlitBlend", "Tests blitting with blending", TEST_DISABLED
|
||||
};
|
||||
|
||||
static const SDLTest_TestCaseReference renderTest8 = {
|
||||
(SDLTest_TestCaseFp)render_testGetSetTextureScaleMode, "render_testGetSetTextureScaleMode", "Tests setting/getting texture scale mode", TEST_ENABLED
|
||||
};
|
||||
|
||||
static const SDLTest_TestCaseReference renderTest9 = {
|
||||
(SDLTest_TestCaseFp)render_testRGBSurfaceNoAlpha, "render_testRGBSurfaceNoAlpha", "Tests RGB surface with no alpha using software renderer", TEST_ENABLED
|
||||
};
|
||||
|
||||
/* Sequence of Render test cases */
|
||||
static const SDLTest_TestCaseReference *renderTests[] = {
|
||||
&renderTest1, &renderTest2, &renderTest3, &renderTest4, &renderTest5, &renderTest6, &renderTest7, NULL
|
||||
&renderTest1, &renderTest2, &renderTest3, &renderTest4, &renderTest5, &renderTest6, &renderTest7, &renderTest8, &renderTest9, NULL
|
||||
};
|
||||
|
||||
/* Render test suite (global) */
|
||||
|
||||
@@ -208,6 +208,42 @@ static int subsystems_dependRefCountWithExtraInit(void)
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Inits and Quits timers subsystem, which cannot be explicitly initialized in SDL3
|
||||
*
|
||||
* \sa SDL_InitSubSystem
|
||||
* \sa SDL_QuitSubSystem
|
||||
*
|
||||
*/
|
||||
static int subsystems_timersSubsystem(void)
|
||||
{
|
||||
int result;
|
||||
/* Ensure that we start with reset subsystems. */
|
||||
SDLTest_AssertCheck(SDL_WasInit(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_EVENTS) == 0,
|
||||
"Check result from SDL_WasInit(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_EVENTS)");
|
||||
|
||||
SDLTest_AssertPass("About to call SDL_WasInit(0)");
|
||||
result = SDL_WasInit(0);
|
||||
SDLTest_AssertCheck(result == 0, "SDL_WasInit(0) should return 0, actual 0x%x", result);
|
||||
|
||||
SDLTest_AssertPass("About to call SDL_InitSubSystem(SDL_INIT_TIMER)");
|
||||
result = SDL_InitSubSystem(SDL_INIT_TIMER);
|
||||
SDLTest_AssertCheck(result == 0, "Must return 0, actually %d", result);
|
||||
SDLTest_AssertPass("About to call SDL_WasInit(SDL_INIT_TIMER)");
|
||||
result = SDL_WasInit(SDL_INIT_TIMER);
|
||||
SDLTest_AssertCheck(result == SDL_INIT_TIMER, "Must return SDL_INIT_TIMER (=%d), actually %d", SDL_INIT_TIMER, result);
|
||||
SDLTest_AssertPass("About to call SDL_WasInit(0)");
|
||||
result = SDL_WasInit(0);
|
||||
SDLTest_AssertCheck(result == SDL_INIT_TIMER, "SDL_WasInit(0) should return SDL_INIT_TIMER, actual 0x%x", result);
|
||||
|
||||
SDLTest_AssertPass("About to call SDL_QuitSubSystem(SDL_INIT_TIMER)");
|
||||
SDL_QuitSubSystem(SDL_INIT_TIMER);
|
||||
SDLTest_AssertPass("SDL_QuitSubSystem finished");
|
||||
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
/* ================= Test References ================== */
|
||||
|
||||
/* Subsystems test cases */
|
||||
@@ -227,9 +263,13 @@ static const SDLTest_TestCaseReference subsystemsTest4 = {
|
||||
(SDLTest_TestCaseFp)subsystems_dependRefCountWithExtraInit, "subsystems_dependRefCountWithExtraInit", "Check reference count of subsystem dependencies.", TEST_ENABLED
|
||||
};
|
||||
|
||||
static const SDLTest_TestCaseReference subsystemsTest5 = {
|
||||
(SDLTest_TestCaseFp)subsystems_timersSubsystem, "subsystems_timersSubsystem", "Check timer subsystem, removed in SDL3.", TEST_ENABLED
|
||||
};
|
||||
|
||||
/* Sequence of Events test cases */
|
||||
static const SDLTest_TestCaseReference *subsystemsTests[] = {
|
||||
&subsystemsTest1, &subsystemsTest2, &subsystemsTest3, &subsystemsTest4, NULL
|
||||
&subsystemsTest1, &subsystemsTest2, &subsystemsTest3, &subsystemsTest4, &subsystemsTest5, NULL
|
||||
};
|
||||
|
||||
/* Events test suite (global) */
|
||||
|
||||
@@ -798,6 +798,56 @@ int surface_testOverflow(void *arg)
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
static int surface_testSetGetClipRect(void *args)
|
||||
{
|
||||
const struct {
|
||||
SDL_Rect r;
|
||||
SDL_bool clipsetval;
|
||||
SDL_bool cmpval;
|
||||
} rect_list[] = {
|
||||
{ { 0, 0, 0, 0}, SDL_FALSE, SDL_TRUE},
|
||||
{ { 2, 2, 0, 0}, SDL_FALSE, SDL_TRUE},
|
||||
{ { 2, 2, 5, 1}, SDL_TRUE, SDL_TRUE},
|
||||
{ { 6, 5, 10, 3}, SDL_TRUE, SDL_FALSE},
|
||||
{ { 0, 0, 10, 10}, SDL_TRUE, SDL_TRUE},
|
||||
{ { 0, 0, -10, 10}, SDL_FALSE, SDL_TRUE},
|
||||
{ { 0, 0, -10, -10}, SDL_FALSE, SDL_TRUE},
|
||||
{ { -10, -10, 10, 10}, SDL_FALSE, SDL_FALSE},
|
||||
{ { 10, -10, 10, 10}, SDL_FALSE, SDL_FALSE},
|
||||
{ { 10, 10, 10, 10}, SDL_TRUE, SDL_FALSE}
|
||||
};
|
||||
SDL_Surface *s;
|
||||
SDL_Rect r;
|
||||
int i;
|
||||
|
||||
SDLTest_AssertPass("About to call SDL_CreateRGBSurface(0, 15, 15, 32, 0, 0, 0, 0)");
|
||||
s = SDL_CreateRGBSurface(0, 15, 15, 32, 0, 0, 0, 0);
|
||||
SDLTest_AssertCheck(s != NULL, "SDL_CreateRGBSurface returned non-null surface");
|
||||
SDL_zero(r);
|
||||
SDL_GetClipRect(s, &r);
|
||||
SDLTest_AssertCheck(r.x == 0 && r.y == 0 && r.w == 15 && r.h == 15,
|
||||
"SDL_GetClipRect of just-created surface. Got {%d, %d, %d, %d}. (Expected {%d, %d, %d, %d})",
|
||||
r.x, r.y, r.w, r.h, 0, 0, 15, 15);
|
||||
|
||||
for (i = 0; i < SDL_arraysize(rect_list); i++) {
|
||||
SDL_bool b;
|
||||
const SDL_Rect *r_in = &rect_list[i].r;
|
||||
SDL_Rect r_out;
|
||||
|
||||
SDLTest_AssertPass("About to do SDL_SetClipRect({%d, %d, %d, %d})", r_in->x, r_in->y, r_in->w, r_in->h);
|
||||
b = SDL_SetClipRect(s, r_in);
|
||||
SDLTest_AssertCheck(b == rect_list[i].clipsetval, "SDL_SetClipRect returned %d (expected %d)", b, rect_list[i].clipsetval);
|
||||
SDL_zero(r_out);
|
||||
SDL_GetClipRect(s, &r_out);
|
||||
SDLTest_AssertPass("SDL_GetClipRect returned {%d, %d, %d, %d}", r_out.x, r_out.y, r_out.w, r_out.h);
|
||||
b = r_out.x == r_in->x && r_out.y == r_in->y && r_out.w == r_in->w && r_out.h == r_in->h;
|
||||
SDLTest_AssertCheck(b == rect_list[i].cmpval, "Current clipping rect is identical to input clipping rect: %d (expected %d)",
|
||||
b, rect_list[i].cmpval);
|
||||
}
|
||||
SDL_FreeSurface(s);
|
||||
return TEST_COMPLETED;
|
||||
};
|
||||
|
||||
/* ================= Test References ================== */
|
||||
|
||||
/* Surface test cases */
|
||||
@@ -856,11 +906,17 @@ static const SDLTest_TestCaseReference surfaceTestOverflow = {
|
||||
surface_testOverflow, "surface_testOverflow", "Test overflow detection.", TEST_ENABLED
|
||||
};
|
||||
|
||||
static const SDLTest_TestCaseReference surfaceTestSetGetClipRect = {
|
||||
surface_testSetGetClipRect, "surface_testSetGetClipRect", "Test SDL_(Set|Get)ClipRect.", TEST_ENABLED
|
||||
};
|
||||
|
||||
/* Sequence of Surface test cases */
|
||||
static const SDLTest_TestCaseReference *surfaceTests[] = {
|
||||
&surfaceTest1, &surfaceTest2, &surfaceTest3, &surfaceTest4, &surfaceTest5,
|
||||
&surfaceTest6, &surfaceTest7, &surfaceTest8, &surfaceTest9, &surfaceTest10,
|
||||
&surfaceTest11, &surfaceTest12, &surfaceTestOverflow, NULL
|
||||
&surfaceTest11, &surfaceTest12, &surfaceTestOverflow,
|
||||
&surfaceTestSetGetClipRect,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Surface test suite (global) */
|
||||
|
||||
@@ -2251,6 +2251,33 @@ static int video_getWindowSurface(void *arg)
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests SDL_SetWindowInputFocus
|
||||
*/
|
||||
static int video_setWindowInputFocus(void *arg)
|
||||
{
|
||||
int result;
|
||||
SDL_Window *window;
|
||||
|
||||
SDLTest_AssertPass("SDL_SetWindowInputFocus is not supported on dummy and SDL2 wayland driver");
|
||||
if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "dummy") == 0 || SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0) {
|
||||
return TEST_SKIPPED;
|
||||
}
|
||||
|
||||
window = _createVideoSuiteTestWindow("video_setWindowInputFocus");
|
||||
if (!window) {
|
||||
return TEST_ABORTED;
|
||||
}
|
||||
|
||||
SDLTest_AssertPass("About to call SDL_SetWindowInputFocus(window)");
|
||||
result = SDL_SetWindowInputFocus(window);
|
||||
SDLTest_AssertCheck(result == 0, "Result is %d, expected 0", result);
|
||||
|
||||
_destroyVideoSuiteTestWindow(window);
|
||||
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
/* ================= Test References ================== */
|
||||
|
||||
/* Video test cases */
|
||||
@@ -2338,6 +2365,9 @@ static const SDLTest_TestCaseReference videoTest24 =
|
||||
static const SDLTest_TestCaseReference videoTest25 = {
|
||||
(SDLTest_TestCaseFp)video_getWindowSurface, "video_getWindowSurface", "Checks window surface functionality", TEST_ENABLED
|
||||
};
|
||||
static const SDLTest_TestCaseReference videoTest26 = {
|
||||
(SDLTest_TestCaseFp)video_setWindowInputFocus, "video_setWindowInputFocus", "Checks window input focus", TEST_ENABLED
|
||||
};
|
||||
|
||||
/* Sequence of Video test cases */
|
||||
static const SDLTest_TestCaseReference *videoTests[] = {
|
||||
@@ -2345,7 +2375,7 @@ static const SDLTest_TestCaseReference *videoTests[] = {
|
||||
&videoTest7, &videoTest8, &videoTest9, &videoTest10, &videoTest11, &videoTest12,
|
||||
&videoTest13, &videoTest14, &videoTest15, &videoTest16, &videoTest17,
|
||||
&videoTest18, &videoTest19, &videoTest20, &videoTest21, &videoTest22,
|
||||
&videoTest23, &videoTest24, &videoTest25, NULL
|
||||
&videoTest23, &videoTest24, &videoTest25, &videoTest26, NULL
|
||||
};
|
||||
|
||||
/* Video test suite (global) */
|
||||
|
||||
Reference in new issue
Block a user