Merge SDL-ryan-batching-renderer branch to default.

Ryan C. Gordon 2018-10-31 15:03:41 -04:00
commit 62494a2e27
215 changed files with 5146 additions and 2712 deletions

View File

@ -102,7 +102,7 @@ include $(CLEAR_VARS)
LOCAL_CPPFLAGS += -std=c++11
LOCAL_SRC_FILES := $(LOCAL_PATH)/src/hidapi/android/hid.cpp
LOCAL_SRC_FILES := src/hidapi/android/hid.cpp
LOCAL_MODULE := libhidapi
LOCAL_LDLIBS := -llog

View File

@ -42,10 +42,13 @@ include(${SDL2_SOURCE_DIR}/cmake/sdlchecks.cmake)
# set SDL_BINARY_AGE and SDL_INTERFACE_AGE to 0.
set(SDL_MAJOR_VERSION 2)
set(SDL_MINOR_VERSION 0)
set(SDL_MICRO_VERSION 8)
set(SDL_MICRO_VERSION 9)
set(SDL_INTERFACE_AGE 0)
set(SDL_BINARY_AGE 8)
set(SDL_BINARY_AGE 9)
set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}")
# the following should match the versions in Xcode project file:
set(DYLIB_CURRENT_VERSION 10.0.0)
set(DYLIB_COMPATIBILITY_VERSION 1.0.0)
# Set defaults preventing destination file conflicts
set(SDL_CMAKE_DEBUG_POSTFIX "d"
@ -334,7 +337,7 @@ foreach(_SUB ${SDL_X11_OPTIONS})
endforeach()
set_option(VIDEO_COCOA "Use Cocoa video driver" ${APPLE})
set_option(DIRECTX "Use DirectX for Windows audio/video" ${WINDOWS})
dep_option(WASAPI "Use the Windows WASAPI audio driver" ON "DIRECTX" OFF)
set_option(WASAPI "Use the Windows WASAPI audio driver" ${WINDOWS})
set_option(RENDER_D3D "Enable the Direct3D render driver" ${WINDOWS})
set_option(VIDEO_VIVANTE "Use Vivante EGL video driver" ${UNIX_SYS})
dep_option(VIDEO_VULKAN "Enable Vulkan support" ON "ANDROID OR APPLE OR LINUX OR WINDOWS" OFF)
@ -451,6 +454,8 @@ if(USE_GCC OR USE_CLANG)
if(APPLE)
list(APPEND EXTRA_LDFLAGS "-Wl,-undefined,error")
list(APPEND EXTRA_LDFLAGS "-Wl,-compatibility_version,${DYLIB_COMPATIBILITY_VERSION}")
list(APPEND EXTRA_LDFLAGS "-Wl,-current_version,${DYLIB_CURRENT_VERSION}")
else()
set(CMAKE_REQUIRED_FLAGS "-Wl,--no-undefined")
check_c_compiler_flag("" HAVE_NO_UNDEFINED)
@ -1059,6 +1064,12 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID)
include_directories(${IBUS_INCLUDE_DIRS})
list(APPEND EXTRA_LIBS ${IBUS_LIBRARIES})
endif()
if(HAVE_LIBUNWIND_H)
# We've already found the header, so REQUIRE the lib to be present
pkg_search_module(UNWIND REQUIRED libunwind)
pkg_search_module(UNWIND_GENERIC REQUIRED libunwind-generic)
list(APPEND EXTRA_LIBS ${UNWIND_LIBRARIES} ${UNWIND_GENERIC_LIBRARIES})
endif()
endif()
check_include_file("fcitx/frontend.h" HAVE_FCITX_FRONTEND_H)
@ -1200,8 +1211,6 @@ elseif(WINDOWS)
check_include_file(ddraw.h HAVE_DDRAW_H)
check_include_file(dsound.h HAVE_DSOUND_H)
check_include_file(dinput.h HAVE_DINPUT_H)
check_include_file(mmdeviceapi.h HAVE_MMDEVICEAPI_H)
check_include_file(audioclient.h HAVE_AUDIOCLIENT_H)
check_include_file(dxgi.h HAVE_DXGI_H)
if(HAVE_D3D_H OR HAVE_D3D11_H OR HAVE_DDRAW_H OR HAVE_DSOUND_H OR HAVE_DINPUT_H)
set(HAVE_DIRECTX TRUE)
@ -1214,6 +1223,11 @@ elseif(WINDOWS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
endif()
# headers needed elsewhere ...
check_include_file(mmdeviceapi.h HAVE_MMDEVICEAPI_H)
check_include_file(audioclient.h HAVE_AUDIOCLIENT_H)
check_include_file(endpointvolume.h HAVE_ENDPOINTVOLUME_H)
if(SDL_AUDIO)
set(SDL_AUDIO_DRIVER_WINMM 1)
file(GLOB WINMM_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/winmm/*.c)
@ -1544,6 +1558,7 @@ endif()
if(VIDEO_VULKAN)
set(SDL_VIDEO_VULKAN 1)
set(HAVE_VIDEO_VULKAN TRUE)
endif()
# Dummies
@ -1555,7 +1570,7 @@ endif()
# This leads to missing internal references on building, since the
# src/X/*.c does not get included.
if(NOT HAVE_SDL_JOYSTICK)
set(SDL_JOYSTICK_DISABLED 1)
set(SDL_JOYSTICK_DUMMY 1)
if(SDL_JOYSTICK AND NOT APPLE) # results in unresolved symbols on OSX
file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/dummy/*.c)
@ -1563,10 +1578,15 @@ if(NOT HAVE_SDL_JOYSTICK)
endif()
endif()
if(NOT HAVE_SDL_HAPTIC)
set(SDL_HAPTIC_DISABLED 1)
set(SDL_HAPTIC_DUMMY 1)
file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/dummy/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${HAPTIC_SOURCES})
endif()
if(NOT HAVE_SDL_SENSORS)
set(SDL_SENSOR_DUMMY 1)
file(GLOB SENSORS_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/dummy/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${SENSORS_SOURCES})
endif()
if(NOT HAVE_SDL_LOADSO)
set(SDL_LOADSO_DISABLED 1)
file(GLOB LOADSO_SOURCES ${SDL2_SOURCE_DIR}/src/loadso/dummy/*.c)
@ -1577,11 +1597,6 @@ if(NOT HAVE_SDL_FILESYSTEM)
file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/dummy/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${FILESYSTEM_SOURCES})
endif()
if(NOT HAVE_SDL_SENSORS)
set(SDL_SENSOR_DISABLED 1)
file(GLOB SENSORS_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/dummy/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${SENSORS_SOURCES})
endif()
# We always need to have threads and timers around
if(NOT HAVE_SDL_THREADS)
@ -1717,7 +1732,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
# Always build SDLmain
add_library(SDL2main STATIC ${SDLMAIN_SOURCES})
target_include_directories(SDL2main PUBLIC $<INSTALL_INTERFACE:include/SDL2>)
target_include_directories(SDL2main PUBLIC "$<BUILD_INTERFACE:${SDL2_SOURCE_DIR}/include>" $<INSTALL_INTERFACE:include/SDL2>)
set(_INSTALL_LIBS "SDL2main")
if (NOT ANDROID)
set_target_properties(SDL2main PROPERTIES DEBUG_POSTFIX ${SDL_CMAKE_DEBUG_POSTFIX})
@ -1726,7 +1741,9 @@ endif()
if(SDL_SHARED)
add_library(SDL2 SHARED ${SOURCE_FILES} ${VERSION_SOURCES})
if(APPLE)
set_target_properties(SDL2 PROPERTIES MACOSX_RPATH 1)
set_target_properties(SDL2 PROPERTIES
MACOSX_RPATH 1
OUTPUT_NAME "SDL2-${LT_RELEASE}")
elseif(UNIX AND NOT ANDROID)
set_target_properties(SDL2 PROPERTIES
VERSION ${LT_VERSION}
@ -1746,7 +1763,7 @@ if(SDL_SHARED)
endif()
set(_INSTALL_LIBS "SDL2" ${_INSTALL_LIBS})
target_link_libraries(SDL2 ${EXTRA_LIBS} ${EXTRA_LDFLAGS})
target_include_directories(SDL2 PUBLIC $<INSTALL_INTERFACE:include/SDL2>)
target_include_directories(SDL2 PUBLIC "$<BUILD_INTERFACE:${SDL2_SOURCE_DIR}/include>" $<INSTALL_INTERFACE:include/SDL2>)
if (NOT ANDROID)
set_target_properties(SDL2 PROPERTIES DEBUG_POSTFIX ${SDL_CMAKE_DEBUG_POSTFIX})
endif()
@ -1772,7 +1789,7 @@ if(SDL_STATIC)
# libraries - do we need to consider this?
set(_INSTALL_LIBS "SDL2-static" ${_INSTALL_LIBS})
target_link_libraries(SDL2-static ${EXTRA_LIBS} ${EXTRA_LDFLAGS})
target_include_directories(SDL2-static PUBLIC $<INSTALL_INTERFACE:include/SDL2>)
target_include_directories(SDL2-static PUBLIC "$<BUILD_INTERFACE:${SDL2_SOURCE_DIR}/include>" $<INSTALL_INTERFACE:include/SDL2>)
if (NOT ANDROID)
set_target_properties(SDL2-static PROPERTIES DEBUG_POSTFIX ${SDL_CMAKE_DEBUG_POSTFIX})
endif()
@ -1839,17 +1856,14 @@ endif()
if(NOT (WINDOWS OR CYGWIN))
if(SDL_SHARED)
if (APPLE)
set(SOEXT "dylib")
else()
set(SOEXT "so")
endif()
set(SOEXT ${CMAKE_SHARED_LIBRARY_SUFFIX}) # ".so", ".dylib", etc.
get_target_property(SONAME SDL2 OUTPUT_NAME)
if(NOT ANDROID)
install(CODE "
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
\"libSDL2-2.0${SOPOSTFIX}.${SOEXT}\" \"libSDL2.${SOEXT}\")"
\"lib${SONAME}${SOPOSTFIX}${SOEXT}\" \"libSDL2${SOPOSTFIX}${SOEXT}\")"
WORKING_DIR "${SDL2_BINARY_DIR}")
install(FILES ${SDL2_BINARY_DIR}/libSDL2.${SOEXT} DESTINATION "lib${LIB_SUFFIX}")
install(FILES ${SDL2_BINARY_DIR}/libSDL2${SOPOSTFIX}${SOEXT} DESTINATION "lib${LIB_SUFFIX}")
endif()
endif()
if(FREEBSD)

126
Makefile.os2 Normal file
View File

@ -0,0 +1,126 @@
# Open Watcom makefile to build SDL2.dll for OS/2:
# wmake -f Makefile.os2
LIBNAME = SDL2
VERSION = 2.0.9
DESCRIPTION = Simple DirectMedia Layer 2
LIBHOME = .
LIBPATH = $(LIBHOME)/lib
DLLFILE = $(LIBHOME)/$(LIBNAME).dll
LIBFILE = $(LIBHOME)/$(LIBNAME).lib
LNKFILE = $(LIBNAME).lnk
INCPATH = -I"$(%WATCOM)/h/os2" -I"$(%WATCOM)/h"
INCPATH+= -I"$(LIBHOME)/h"
INCPATH+= -Iinclude
LIBS = mmpm2.lib libuls.lib libconv.lib
CFLAGS = -bt=os2 -d0 -q -bm -5s -fp5 -fpi87 -sg -oteanbmier -ei
# max warnings:
CFLAGS+= -wx
# building dll:
CFLAGS+= -bd
# the include paths :
CFLAGS+= $(INCPATH)
# building SDL itself:
CFLAGS+= -DBUILD_SDL
SRCS = SDL.c SDL_assert.c SDL_error.c SDL_log.c SDL_dataqueue.c SDL_hints.c
SRCS+= SDL_getenv.c SDL_iconv.c SDL_malloc.c SDL_qsort.c SDL_stdlib.c SDL_string.c
SRCS+= SDL_cpuinfo.c SDL_atomic.c SDL_spinlock.c SDL_thread.c SDL_timer.c
SRCS+= SDL_rwops.c SDL_power.c
SRCS+= SDL_audio.c SDL_audiocvt.c SDL_audiodev.c SDL_audiotypecvt.c SDL_mixer.c SDL_wave.c
SRCS+= SDL_events.c SDL_quit.c SDL_keyboard.c SDL_mouse.c SDL_windowevents.c &
SDL_clipboardevents.c SDL_dropevents.c SDL_displayevents.c SDL_gesture.c &
SDL_sensor.c SDL_touch.c
SRCS+= SDL_haptic.c SDL_gamecontroller.c SDL_joystick.c
SRCS+= SDL_render.c yuv_rgb.c SDL_yuv.c SDL_yuv_sw.c SDL_blendfillrect.c &
SDL_blendline.c SDL_blendpoint.c SDL_drawline.c SDL_drawpoint.c &
SDL_render_sw.c SDL_rotate.c
SRCS+= SDL_blit.c SDL_blit_0.c SDL_blit_1.c SDL_blit_A.c SDL_blit_auto.c &
SDL_blit_copy.c SDL_blit_N.c SDL_blit_slow.c SDL_fillrect.c SDL_bmp.c &
SDL_pixels.c SDL_rect.c SDL_RLEaccel.c SDL_shape.c SDL_stretch.c &
SDL_surface.c SDL_video.c SDL_clipboard.c SDL_vulkan_utils.c SDL_egl.c
SRCS+= SDL_syscond.c SDL_sysmutex.c SDL_syssem.c SDL_systhread.c SDL_systls.c
SRCS+= SDL_systimer.c
SRCS+= SDL_sysloadso.c
SRCS+= SDL_sysfilesystem.c
SRCS+= SDL_syshaptic.c SDL_sysjoystick.c
SRCS+= SDL_dummyaudio.c SDL_diskaudio.c
SRCS+= SDL_nullvideo.c SDL_nullframebuffer.c SDL_nullevents.c
SRCS+= SDL_dummysensor.c
SRCS+= SDL_dynapi.c
OBJS = $(SRCS:.c=.obj)
.extensions:
.extensions: .lib .dll .obj .c .asm
.c: ./src;./src/dynapi;./src/audio;./src/cpuinfo;./src/events;./src/file;./src/haptic;./src/joystick;./src/power;./src/render;./src/render/software;./src/sensor;./src/stdlib;./src/thread;./src/timer;./src/video;./src/video/yuv2rgb;./src/atomic;./src/audio/disk;
.c: ./src/haptic/dummy;./src/joystick/dummy;./src/audio/dummy;./src/video/dummy;./src/sensor/dummy;
.c: ./src/loadso/dummy;./src/filesystem/dummy;./src/timer/dummy;./src/thread/generic;
all: $(DLLFILE) $(LIBFILE) .symbolic
$(DLLFILE): $(OBJS) $(LNKFILE)
@echo * Linking: $@
wlink @$(LNKFILE)
$(LIBFILE): $(DLLFILE)
@echo * Creating LIB file: $@
wlib -q -b -n -c -pa -s -t -zld -ii -io $* $(DLLFILE)
.c.obj:
wcc386 $(CFLAGS) -fo=$^@ $<
SDL_cpuinfo.obj: SDL_cpuinfo.c
wcc386 $(CFLAGS) -wcd=200 -fo=$^@ $<
SDL_rwops.obj: SDL_rwops.c
wcc386 $(CFLAGS) -wcd=136 -fo=$^@ $<
SDL_blendfillrect.obj: SDL_blendfillrect.c
wcc386 $(CFLAGS) -wcd=200 -fo=$^@ $<
SDL_blendline.obj: SDL_blendline.c
wcc386 $(CFLAGS) -wcd=200 -fo=$^@ $<
SDL_blendpoint.obj: SDL_blendpoint.c
wcc386 $(CFLAGS) -wcd=200 -fo=$^@ $<
SDL_RLEaccel.obj: SDL_RLEaccel.c
wcc386 $(CFLAGS) -wcd=201 -fo=$^@ $<
$(LNKFILE):
@echo * Creating linker file: $@
@%create $@
@%append $@ SYSTEM os2v2_dll INITINSTANCE TERMINSTANCE
@%append $@ NAME $(DLLFILE)
@for %i in ($(OBJS)) do @%append $@ FILE %i
@%append $@ LIBPATH $(%LIB);$(LIBPATH)
@for %i in ($(LIBS)) do @%append $@ LIB %i
@%append $@ OPTION QUIET
@%append $@ OPTION IMPF=$(LIBHOME)/$^&.exp
@%append $@ OPTION MAP=$(LIBHOME)/$^&.map
@%append $@ OPTION DESCRIPTION '@$#libsdl org:$(VERSION)$#@$(DESCRIPTION)'
@%append $@ OPTION QUIET
@%append $@ OPTION ELIMINATE
@%append $@ OPTION MANYAUTODATA
@%append $@ OPTION OSNAME='OS/2 and eComStation'
@%append $@ OPTION SHOWDEAD
clean: .SYMBOLIC
@ echo * Clean: $(LIBNAME)
@if exist *.obj rm *.obj
@if exist *.err rm *.err
@if exist $(LNKFILE) rm $(LNKFILE)
distclean: .SYMBOLIC clean
@if exist $(LIBHOME)/*.exp rm $(LIBHOME)/*.exp
@if exist $(LIBHOME)/*.map rm $(LIBHOME)/*.map
@if exist $(LIBFILE) rm $(LIBFILE)
@if exist $(DLLFILE) rm $(DLLFILE)

View File

@ -6,7 +6,40 @@ This is a list of major changes in SDL's version history.
---------------------------------------------------------------------------
General:
* Added a new sensor API, initialized by passing SDL_INIT_SENSOR to SDL_Init(), and defined in SDL_sensor.h
* Added an event SDL_SENSORUPDATE which is sent when a sensor is updated
* Added SDL_GetDisplayOrientation() to return the current display orientation
* Added an event SDL_DISPLAYEVENT which is sent when the display orientation changes
* Added HIDAPI joystick drivers for more consistent support for Xbox, PS4 and Nintendo Switch Pro controller support across platforms. (Thanks to Valve for contributing the PS4 and Nintendo Switch Pro controller support)
* Added support for many other popular game controllers
* Added SDL_JoystickGetDevicePlayerIndex(), SDL_JoystickGetPlayerIndex(), and SDL_GameControllerGetPlayerIndex() to get the player index for a controller. For XInput controllers this returns the XInput index for the controller.
* Added SDL_GameControllerRumble() and SDL_JoystickRumble() which allow simple rumble without using the haptics API
* Added SDL_GameControllerMappingForDeviceIndex() to get the mapping for a controller before it's opened
* Added the hint SDL_HINT_MOUSE_DOUBLE_CLICK_TIME to control the mouse double-click time
* Added the hint SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS to control the mouse double-click radius, in pixels
* Added SDL_HasColorKey() to return whether a surface has a colorkey active
* Added SDL_HasAVX512F() to return whether the CPU has AVX-512F features
* Added SDL_IsTablet() to return whether the application is running on a tablet
* Added SDL_THREAD_PRIORITY_TIME_CRITICAL for threads that must run at the highest priority
Mac OS X:
* Fixed black screen at start on Mac OS X Mojave
Linux:
* Added SDL_LinuxSetThreadPriority() to allow adjusting the thread priority of native threads using RealtimeKit if available.
iOS:
* Fixed Asian IME input
Android:
* Updated required Android SDK to API 26, to match Google's new App Store requirements
* Added support for wired USB Xbox, PS4, and Nintendo Switch Pro controllers
* Added support for relative mouse mode on Android 7.0 and newer (except where it's broken, on Chromebooks and when in DeX mode with Samsung Experience 9.0)
* Added support for custom mouse cursors on Android 7.0 and newer
* Added the hint SDL_HINT_ANDROID_TRAP_BACK_BUTTON to control whether the back button will back out of the app (the default) or be passed to the application as SDL_SCANCODE_AC_BACK
* Added SDL_AndroidBackButton() to trigger the Android system back button behavior when handling the back button in the application
* Added SDL_IsChromebook() to return whether the app is running in the Chromebook Android runtime
* Added SDL_IsDeXMode() to return whether the app is running while docked in the Samsung DeX
---------------------------------------------------------------------------

View File

@ -975,6 +975,7 @@
C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_OPTIMIZATION_LEVEL = 0;
HEADER_SEARCH_PATHS = ../../include;
@ -988,6 +989,7 @@
C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
HEADER_SEARCH_PATHS = ../../include;
PRELINK_LIBS = "";

View File

@ -208,6 +208,9 @@
F30D9CA7212CD0BF0047DF2E /* SDL_coremotionsensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F30D9CA4212CD0BF0047DF2E /* SDL_coremotionsensor.h */; };
F30D9CC6212CE92C0047DF2E /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = F30D9CC5212CE92C0047DF2E /* hid.m */; };
F30D9CC7212CE92C0047DF2E /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = F30D9CC5212CE92C0047DF2E /* hid.m */; };
F36839CC214790950000F255 /* SDL_dummysensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F36839CA214790950000F255 /* SDL_dummysensor.h */; };
F36839CD214790950000F255 /* SDL_dummysensor.c in Sources */ = {isa = PBXBuildFile; fileRef = F36839CB214790950000F255 /* SDL_dummysensor.c */; };
F36839CE214790950000F255 /* SDL_dummysensor.c in Sources */ = {isa = PBXBuildFile; fileRef = F36839CB214790950000F255 /* SDL_dummysensor.c */; };
F3BDD79220F51CB8004ECBF3 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = F3BDD78B20F51CB8004ECBF3 /* SDL_hidapi_xbox360.c */; };
F3BDD79320F51CB8004ECBF3 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = F3BDD78B20F51CB8004ECBF3 /* SDL_hidapi_xbox360.c */; };
F3BDD79420F51CB8004ECBF3 /* SDL_hidapi_switch.c in Sources */ = {isa = PBXBuildFile; fileRef = F3BDD78C20F51CB8004ECBF3 /* SDL_hidapi_switch.c */; };
@ -542,6 +545,8 @@
F30D9CA3212CD0BF0047DF2E /* SDL_coremotionsensor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_coremotionsensor.m; sourceTree = "<group>"; };
F30D9CA4212CD0BF0047DF2E /* SDL_coremotionsensor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_coremotionsensor.h; sourceTree = "<group>"; };
F30D9CC5212CE92C0047DF2E /* hid.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = hid.m; sourceTree = "<group>"; };
F36839CA214790950000F255 /* SDL_dummysensor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dummysensor.h; sourceTree = "<group>"; };
F36839CB214790950000F255 /* SDL_dummysensor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_dummysensor.c; sourceTree = "<group>"; };
F3BDD78B20F51CB8004ECBF3 /* SDL_hidapi_xbox360.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_xbox360.c; sourceTree = "<group>"; };
F3BDD78C20F51CB8004ECBF3 /* SDL_hidapi_switch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_switch.c; sourceTree = "<group>"; };
F3BDD78D20F51CB8004ECBF3 /* SDL_hidapi_xboxone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_xboxone.c; sourceTree = "<group>"; };
@ -838,6 +843,7 @@
isa = PBXGroup;
children = (
F30D9CA2212CD09E0047DF2E /* coremotion */,
F36839C9214790740000F255 /* dummy */,
F30D9C9B212CD0980047DF2E /* SDL_sensor_c.h */,
F30D9C9D212CD0990047DF2E /* SDL_sensor.c */,
F30D9C9C212CD0990047DF2E /* SDL_syssensor.h */,
@ -862,6 +868,15 @@
path = hidapi;
sourceTree = "<group>";
};
F36839C9214790740000F255 /* dummy */ = {
isa = PBXGroup;
children = (
F36839CB214790950000F255 /* SDL_dummysensor.c */,
F36839CA214790950000F255 /* SDL_dummysensor.h */,
);
path = dummy;
sourceTree = "<group>";
};
F3BDD77420F51C18004ECBF3 /* ios */ = {
isa = PBXGroup;
children = (
@ -1370,6 +1385,7 @@
AA9FF9511637C6E5000DF050 /* SDL_messagebox.h in Headers */,
AABCC3941640643D00AB8930 /* SDL_uikitmessagebox.h in Headers */,
AA0AD06516647BD400CE5896 /* SDL_gamecontroller.h in Headers */,
F36839CC214790950000F255 /* SDL_dummysensor.h in Headers */,
AADA5B8F16CCAB7C00107CF7 /* SDL_bits.h in Headers */,
56C181DF17C44D5E00406AE3 /* SDL_filesystem.h in Headers */,
);
@ -1565,6 +1581,7 @@
FAB598731BB5C31600BE72C5 /* SDL_iconv.c in Sources */,
FAB598741BB5C31600BE72C5 /* SDL_malloc.c in Sources */,
FAB598751BB5C31600BE72C5 /* SDL_qsort.c in Sources */,
F36839CE214790950000F255 /* SDL_dummysensor.c in Sources */,
A7C19D2B212E552C00DF2152 /* SDL_displayevents.c in Sources */,
FAB598761BB5C31600BE72C5 /* SDL_stdlib.c in Sources */,
FAB598771BB5C31600BE72C5 /* SDL_string.c in Sources */,
@ -1720,6 +1737,7 @@
0442EC5512FE1C3F004C9285 /* SDL_hints.c in Sources */,
AA13B34A1FB8B27800D9FEE6 /* SDL_shape.c in Sources */,
0402A85812FE70C600CECEE3 /* SDL_render_gles2.c in Sources */,
F36839CD214790950000F255 /* SDL_dummysensor.c in Sources */,
0402A85912FE70C600CECEE3 /* SDL_shaders_gles2.c in Sources */,
04BAC09D1300C1290055DE28 /* SDL_log.c in Sources */,
56EA86FB13E9EC2B002E47EB /* SDL_coreaudio.m in Sources */,
@ -1955,6 +1973,7 @@
FD6526640DE8FCCB002AD96B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
@ -1971,6 +1990,7 @@
FD6526650DE8FCCB002AD96B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;

View File

@ -26,34 +26,6 @@
047A63E813285C3200CD7973 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89D0E2D111A00EA573E /* Foundation.framework */; };
047A63E913285C3200CD7973 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89E0E2D111A00EA573E /* CoreAudio.framework */; };
047A63F113285CD100CD7973 /* checkkeys.c in Sources */ = {isa = PBXBuildFile; fileRef = 047A63F013285CD100CD7973 /* checkkeys.c */; };
55FFA91C212232BA00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA91D212232BF00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA91E212232BF00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA91F212232C000D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA920212232C000D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA921212232C100D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA922212232C100D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA923212232C200D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA924212232C200D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA925212232C300D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA926212232C300D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA927212232C500D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA928212232C500D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA929212232C600D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA92A212232C600D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA92B212232C700D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA92C212232C700D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA92D212232C800D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA92E212232CA00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA92F212232CA00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA930212232CB00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA931212232CB00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA932212232CC00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA933212232CC00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA934212232CD00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA935212232CE00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA936212232CE00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA937212232CF00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
56ED04FE118A8FE400A56AA6 /* icon.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FDA8AAD90E2D33B000EA573E /* icon.bmp */; };
56ED0502118A8FE400A56AA6 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD1B48B80E3131CA007AB34E /* libSDL2.a */; };
56ED0503118A8FE400A56AA6 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A8980E2D111A00EA573E /* AudioToolbox.framework */; };
@ -451,7 +423,6 @@
047A63ED13285C3200CD7973 /* checkkeys.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = checkkeys.app; sourceTree = BUILT_PRODUCTS_DIR; };
047A63F013285CD100CD7973 /* checkkeys.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = checkkeys.c; sourceTree = "<group>"; };
1D6058910D05DD3D006BFB54 /* testwm2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testwm2.app; sourceTree = BUILT_PRODUCTS_DIR; };
55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreBluetooth.framework; path = System/Library/Frameworks/CoreBluetooth.framework; sourceTree = SDKROOT; };
56ED050D118A8FE400A56AA6 /* testpower.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testpower.app; sourceTree = BUILT_PRODUCTS_DIR; };
56ED0510118A904200A56AA6 /* testpower.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testpower.c; sourceTree = "<group>"; };
AA13B3261FB8AEBC00D9FEE6 /* testyuv.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testyuv.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -543,7 +514,6 @@
046CEF7F13254F23007AD51D /* CoreGraphics.framework in Frameworks */,
046CEF8013254F23007AD51D /* UIKit.framework in Frameworks */,
046CEF8113254F23007AD51D /* Foundation.framework in Frameworks */,
55FFA926212232C300D7CBED /* CoreBluetooth.framework in Frameworks */,
046CEF8213254F23007AD51D /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -552,7 +522,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
55FFA91C212232BA00D7CBED /* CoreBluetooth.framework in Frameworks */,
FABA34B01D8B5B6400915323 /* AVFoundation.framework in Frameworks */,
AA1EE470176059D00029C7A5 /* libSDL2test.a in Frameworks */,
047A63E213285C3200CD7973 /* libSDL2.a in Frameworks */,
@ -575,7 +544,6 @@
FABA34C41D8B5BCB00915323 /* AVFoundation.framework in Frameworks */,
AA1EE47817605BF60029C7A5 /* libSDL2test.a in Frameworks */,
FDBDE5810E313465006BAC0B /* libSDL2.a in Frameworks */,
55FFA935212232CE00D7CBED /* CoreBluetooth.framework in Frameworks */,
FA684F931BAF1A8A00DCFD1A /* GameController.framework in Frameworks */,
FA8B4BE0196766F400F8EB7C /* CoreMotion.framework in Frameworks */,
FDA8A89F0E2D111A00EA573E /* AudioToolbox.framework in Frameworks */,
@ -602,7 +570,6 @@
56ED0506118A8FE400A56AA6 /* CoreGraphics.framework in Frameworks */,
56ED0507118A8FE400A56AA6 /* UIKit.framework in Frameworks */,
56ED0508118A8FE400A56AA6 /* Foundation.framework in Frameworks */,
55FFA92D212232C800D7CBED /* CoreBluetooth.framework in Frameworks */,
56ED0509118A8FE400A56AA6 /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -614,7 +581,6 @@
AA13B3171FB8AEBC00D9FEE6 /* AVFoundation.framework in Frameworks */,
AA13B3181FB8AEBC00D9FEE6 /* libSDL2test.a in Frameworks */,
AA13B3191FB8AEBC00D9FEE6 /* libSDL2.a in Frameworks */,
55FFA936212232CE00D7CBED /* CoreBluetooth.framework in Frameworks */,
AA13B31A1FB8AEBC00D9FEE6 /* GameController.framework in Frameworks */,
AA13B31B1FB8AEBC00D9FEE6 /* CoreMotion.framework in Frameworks */,
AA13B31C1FB8AEBC00D9FEE6 /* AudioToolbox.framework in Frameworks */,
@ -634,7 +600,6 @@
FABA34BE1D8B5BB000915323 /* AVFoundation.framework in Frameworks */,
AA1EE47617605B9E0029C7A5 /* libSDL2test.a in Frameworks */,
AAE7DEE114CBB1E100DF1A0E /* libSDL2.a in Frameworks */,
55FFA92F212232CA00D7CBED /* CoreBluetooth.framework in Frameworks */,
FA684F8D1BAF1A7800DCFD1A /* GameController.framework in Frameworks */,
FA8B4BDA196766E200F8EB7C /* CoreMotion.framework in Frameworks */,
AAE7DEE214CBB1E100DF1A0E /* AudioToolbox.framework in Frameworks */,
@ -655,7 +620,6 @@
FABA34BD1D8B5BAB00915323 /* AVFoundation.framework in Frameworks */,
AA1EE47517605B930029C7A5 /* libSDL2test.a in Frameworks */,
AAE7DFA614CBB54E00DF1A0E /* libSDL2.a in Frameworks */,
55FFA92E212232CA00D7CBED /* CoreBluetooth.framework in Frameworks */,
FA684F8C1BAF1A7400DCFD1A /* GameController.framework in Frameworks */,
FA8B4BD9196766E000F8EB7C /* CoreMotion.framework in Frameworks */,
AAE7DFA714CBB54E00DF1A0E /* AudioToolbox.framework in Frameworks */,
@ -680,7 +644,6 @@
FA3D994D1BC4E6AD002C96C8 /* CoreGraphics.framework in Frameworks */,
FA3D994E1BC4E6AD002C96C8 /* UIKit.framework in Frameworks */,
FA3D994F1BC4E6AD002C96C8 /* Foundation.framework in Frameworks */,
55FFA925212232C300D7CBED /* CoreBluetooth.framework in Frameworks */,
FA3D99501BC4E6AD002C96C8 /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -699,7 +662,6 @@
FABA348A1D8B575200915323 /* CoreGraphics.framework in Frameworks */,
FABA348B1D8B575200915323 /* UIKit.framework in Frameworks */,
FABA348C1D8B575200915323 /* Foundation.framework in Frameworks */,
55FFA91D212232BF00D7CBED /* CoreBluetooth.framework in Frameworks */,
FABA348D1D8B575200915323 /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -718,7 +680,6 @@
FABA34A31D8B582100915323 /* CoreGraphics.framework in Frameworks */,
FABA34A41D8B582100915323 /* UIKit.framework in Frameworks */,
FABA34A51D8B582100915323 /* Foundation.framework in Frameworks */,
55FFA91F212232C000D7CBED /* CoreBluetooth.framework in Frameworks */,
FABA34A61D8B582100915323 /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -737,7 +698,6 @@
FAE0E98C1BAF9B230098DFA4 /* CoreGraphics.framework in Frameworks */,
FAE0E98D1BAF9B230098DFA4 /* UIKit.framework in Frameworks */,
FAE0E98E1BAF9B230098DFA4 /* Foundation.framework in Frameworks */,
55FFA924212232C200D7CBED /* CoreBluetooth.framework in Frameworks */,
FAE0E98F1BAF9B230098DFA4 /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -756,7 +716,6 @@
FDA8AAB40E2D330F00EA573E /* CoreGraphics.framework in Frameworks */,
FDA8AAB50E2D330F00EA573E /* UIKit.framework in Frameworks */,
FDA8AAB60E2D330F00EA573E /* Foundation.framework in Frameworks */,
55FFA91E212232BF00D7CBED /* CoreBluetooth.framework in Frameworks */,
FDA8AAB70E2D330F00EA573E /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -775,7 +734,6 @@
FDAAC3C60E2D47E6001DB1D8 /* CoreGraphics.framework in Frameworks */,
FDAAC3C70E2D47E6001DB1D8 /* UIKit.framework in Frameworks */,
FDAAC3C80E2D47E6001DB1D8 /* Foundation.framework in Frameworks */,
55FFA920212232C000D7CBED /* CoreBluetooth.framework in Frameworks */,
FDAAC3C90E2D47E6001DB1D8 /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -794,7 +752,6 @@
FDAAC5940E2D5429001DB1D8 /* CoreGraphics.framework in Frameworks */,
FDAAC5950E2D5429001DB1D8 /* UIKit.framework in Frameworks */,
FDAAC5960E2D5429001DB1D8 /* Foundation.framework in Frameworks */,
55FFA923212232C200D7CBED /* CoreBluetooth.framework in Frameworks */,
FDAAC5970E2D5429001DB1D8 /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -813,7 +770,6 @@
FDAAC5C20E2D55B5001DB1D8 /* CoreGraphics.framework in Frameworks */,
FDAAC5C30E2D55B5001DB1D8 /* UIKit.framework in Frameworks */,
FDAAC5C40E2D55B5001DB1D8 /* Foundation.framework in Frameworks */,
55FFA922212232C100D7CBED /* CoreBluetooth.framework in Frameworks */,
FDAAC5C50E2D55B5001DB1D8 /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -825,7 +781,6 @@
FABA34B61D8B5B8900915323 /* AVFoundation.framework in Frameworks */,
AA1EE47417605B5C0029C7A5 /* libSDL2test.a in Frameworks */,
FDBDE57C0E313445006BAC0B /* libSDL2.a in Frameworks */,
55FFA927212232C500D7CBED /* CoreBluetooth.framework in Frameworks */,
FA684F851BAF1A6000DCFD1A /* GameController.framework in Frameworks */,
FA8B4BD2196766CB00F8EB7C /* CoreMotion.framework in Frameworks */,
FDAAC61C0E2D5914001DB1D8 /* AudioToolbox.framework in Frameworks */,
@ -846,7 +801,6 @@
FABA34B21D8B5B7300915323 /* AVFoundation.framework in Frameworks */,
AA1EE47117605A7F0029C7A5 /* libSDL2test.a in Frameworks */,
FDC42FF40F0D866D009C87E1 /* libSDL2.a in Frameworks */,
55FFA921212232C100D7CBED /* CoreBluetooth.framework in Frameworks */,
FA684F811BAF1A5300DCFD1A /* GameController.framework in Frameworks */,
FA8B4BCE196766C100F8EB7C /* CoreMotion.framework in Frameworks */,
FDC42FF60F0D866D009C87E1 /* AudioToolbox.framework in Frameworks */,
@ -873,7 +827,6 @@
FDD2C1030E2E4F4B00B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C1040E2E4F4B00B7A85F /* UIKit.framework in Frameworks */,
FDD2C1050E2E4F4B00B7A85F /* Foundation.framework in Frameworks */,
55FFA932212232CC00D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C1060E2E4F4B00B7A85F /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -892,7 +845,6 @@
FDD2C17A0E2E52C000B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C17B0E2E52C000B7A85F /* UIKit.framework in Frameworks */,
FDD2C17C0E2E52C000B7A85F /* Foundation.framework in Frameworks */,
55FFA928212232C500D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C17D0E2E52C000B7A85F /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -911,7 +863,6 @@
FDD2C19E0E2E534F00B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C19F0E2E534F00B7A85F /* UIKit.framework in Frameworks */,
FDD2C1A00E2E534F00B7A85F /* Foundation.framework in Frameworks */,
55FFA929212232C600D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C1A10E2E534F00B7A85F /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -930,7 +881,6 @@
FDD2C4570E2E773800B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C4580E2E773800B7A85F /* UIKit.framework in Frameworks */,
FDD2C4590E2E773800B7A85F /* Foundation.framework in Frameworks */,
55FFA92A212232C600D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C45A0E2E773800B7A85F /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -949,7 +899,6 @@
FDD2C4750E2E77D700B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C4760E2E77D700B7A85F /* UIKit.framework in Frameworks */,
FDD2C4770E2E77D700B7A85F /* Foundation.framework in Frameworks */,
55FFA92B212232C700D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C4780E2E77D700B7A85F /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -968,7 +917,6 @@
FDD2C5040E2E7F4800B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C5050E2E7F4800B7A85F /* UIKit.framework in Frameworks */,
FDD2C5060E2E7F4800B7A85F /* Foundation.framework in Frameworks */,
55FFA92C212232C700D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C5070E2E7F4800B7A85F /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -987,7 +935,6 @@
FDD2C5220E2E807600B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C5230E2E807600B7A85F /* UIKit.framework in Frameworks */,
FDD2C5240E2E807600B7A85F /* Foundation.framework in Frameworks */,
55FFA930212232CB00D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C5250E2E807600B7A85F /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -1000,7 +947,6 @@
FABA34C01D8B5BBA00915323 /* AVFoundation.framework in Frameworks */,
AA1EE47717605BAB0029C7A5 /* libSDL2test.a in Frameworks */,
FDBDE5CA0E313712006BAC0B /* libSDL2.a in Frameworks */,
55FFA931212232CB00D7CBED /* CoreBluetooth.framework in Frameworks */,
FA684F8F1BAF1A7E00DCFD1A /* GameController.framework in Frameworks */,
FA8B4BDC196766E800F8EB7C /* CoreMotion.framework in Frameworks */,
FDD2C5440E2E80E400B7A85F /* AudioToolbox.framework in Frameworks */,
@ -1027,7 +973,6 @@
FDD2C5800E2E8C7400B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C5810E2E8C7400B7A85F /* UIKit.framework in Frameworks */,
FDD2C5820E2E8C7400B7A85F /* Foundation.framework in Frameworks */,
55FFA934212232CD00D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C5830E2E8C7400B7A85F /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -1046,7 +991,6 @@
FDD2C5BE0E2E8CFC00B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C5BF0E2E8CFC00B7A85F /* UIKit.framework in Frameworks */,
FDD2C5C00E2E8CFC00B7A85F /* Foundation.framework in Frameworks */,
55FFA933212232CC00D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C5C10E2E8CFC00B7A85F /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -1065,7 +1009,6 @@
FDD2C6ED0E2E959E00B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C6EE0E2E959E00B7A85F /* UIKit.framework in Frameworks */,
FDD2C6EF0E2E959E00B7A85F /* Foundation.framework in Frameworks */,
55FFA937212232CF00D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C6F00E2E959E00B7A85F /* CoreAudio.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -1188,7 +1131,6 @@
FDA8A7C30E2D10FA00EA573E /* Frameworks */ = {
isa = PBXGroup;
children = (
55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */,
FA684F7A1BAF1A4400DCFD1A /* GameController.framework */,
FA8B4BAC1967076F00F8EB7C /* CoreMotion.framework */,
FDA8A8980E2D111A00EA573E /* AudioToolbox.framework */,
@ -2384,6 +2326,7 @@
C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
ENABLE_BITCODE = NO;
GCC_OPTIMIZATION_LEVEL = 0;
@ -2400,6 +2343,7 @@
C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
ENABLE_BITCODE = NO;
HEADER_SEARCH_PATHS = ../../include;

View File

@ -19,10 +19,10 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.0.8</string>
<string>2.0.9</string>
<key>CFBundleSignature</key>
<string>SDLX</string>
<key>CFBundleVersion</key>
<string>2.0.8</string>
<string>2.0.9</string>
</dict>
</plist>

View File

@ -2614,7 +2614,7 @@
0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0900;
LastUpgradeCheck = 1000;
};
buildConfigurationList = 0073178E0858DB0500B2BC32 /* Build configuration list for PBXProject "SDL" */;
compatibilityVersion = "Xcode 3.2";
@ -3107,16 +3107,19 @@
00CFA621106A567900758660 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
@ -3153,11 +3156,11 @@
00CFA622106A567900758660 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_LINK_OBJC_RUNTIME = NO;
COMBINE_HIDPI_IMAGES = YES;
DYLIB_COMPATIBILITY_VERSION = 1.0.0;
DYLIB_CURRENT_VERSION = 9.0.0;
DYLIB_CURRENT_VERSION = 10.0.0;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)",
@ -3176,6 +3179,7 @@
00CFA623106A567900758660 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COMBINE_HIDPI_IMAGES = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(GCC_PREPROCESSOR_DEFINITIONS)",
@ -3193,6 +3197,7 @@
00CFA625106A567900758660 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
PRODUCT_NAME = "Standard DMG";
PROVISIONING_PROFILE = "";
};
@ -3201,16 +3206,19 @@
00CFA627106A568900758660 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
@ -3247,11 +3255,11 @@
00CFA628106A568900758660 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_LINK_OBJC_RUNTIME = NO;
COMBINE_HIDPI_IMAGES = YES;
DYLIB_COMPATIBILITY_VERSION = 1.0.0;
DYLIB_CURRENT_VERSION = 9.0.0;
DYLIB_CURRENT_VERSION = 10.0.0;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)",
@ -3270,6 +3278,7 @@
00CFA629106A568900758660 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COMBINE_HIDPI_IMAGES = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(GCC_PREPROCESSOR_DEFINITIONS)",
@ -3287,6 +3296,7 @@
00CFA62B106A568900758660 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
PRODUCT_NAME = "Standard DMG";
PROVISIONING_PROFILE = "";
};
@ -3295,6 +3305,7 @@
DB31407517554B71006C0E22 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COMBINE_HIDPI_IMAGES = YES;
EXECUTABLE_PREFIX = lib;
GCC_PREPROCESSOR_DEFINITIONS = (
@ -3314,6 +3325,7 @@
DB31407617554B71006C0E22 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COMBINE_HIDPI_IMAGES = YES;
EXECUTABLE_PREFIX = lib;
GCC_PREPROCESSOR_DEFINITIONS = (

View File

@ -4040,6 +4040,7 @@
002A85B21073008E007319AE /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(SRCROOT)/../SDL/build/$(CONFIGURATION)",
"$(HOME)/Library/Frameworks",
@ -4166,6 +4167,7 @@
002A85D41073009D007319AE /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(SRCROOT)/../SDL/build/$(CONFIGURATION)",
"$(HOME)/Library/Frameworks",

View File

@ -9,7 +9,6 @@ else {
android {
compileSdkVersion 26
buildToolsVersion "26.0.1"
defaultConfig {
if (buildAsApplication) {
applicationId "org.libsdl.app"
@ -21,10 +20,9 @@ android {
externalNativeBuild {
ndkBuild {
arguments "APP_PLATFORM=android-14"
abiFilters 'armeabi-v7a', 'x86'
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
}
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
@ -61,9 +59,5 @@ android {
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile 'junit:junit:4.12'
implementation fileTree(include: ['*.jar'], dir: 'libs')
}

View File

@ -1,7 +1,8 @@
# Uncomment this if you're using STL in your project
# See CPLUSPLUS-SUPPORT.html in the NDK documentation for more information
# APP_STL := stlport_static
# You can find more information here:
# https://developer.android.com/ndk/guides/cpp-support
# APP_STL := c++_shared
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64

View File

@ -8,9 +8,6 @@
android:versionName="1.0"
android:installLocation="auto">
<!-- Android 4.0.1 -->
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="16" />
<!-- OpenGL ES 2.0 -->
<uses-feature android:glEsVersion="0x00020000" />

View File

@ -479,7 +479,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
// Enable this for verbose logging of controller input reports
//Log.v(TAG, "onCharacteristicChanged uuid=" + characteristic.getUuid() + " data=" + HexDump.dumpHexString(characteristic.getValue()));
if (characteristic.getUuid().equals(inputCharacteristic)) {
if (characteristic.getUuid().equals(inputCharacteristic) && !mFrozen) {
mManager.HIDDeviceInputReport(getId(), characteristic.getValue());
}
}
@ -577,7 +577,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
}
// We need to skip the first byte, as that doesn't go over the air
byte[] actual_report = Arrays.copyOfRange(report, 1, report.length - 1);
byte[] actual_report = Arrays.copyOfRange(report, 1, report.length - 1);
//Log.v(TAG, "sendFeatureReport " + HexDump.dumpHexString(actual_report));
writeCharacteristic(reportCharacteristic, actual_report);
return report.length;
@ -624,6 +624,8 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
@Override
public void shutdown() {
close();
BluetoothGatt g = mGatt;
if (g != null) {
g.disconnect();

View File

@ -1,5 +1,7 @@
package org.libsdl.app;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
@ -8,6 +10,7 @@ import android.bluetooth.BluetoothProfile;
import android.util.Log;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
@ -24,7 +27,28 @@ public class HIDDeviceManager {
private static final String TAG = "hidapi";
private static final String ACTION_USB_PERMISSION = "org.libsdl.app.USB_PERMISSION";
protected Context mContext;
private static HIDDeviceManager sManager;
private static int sManagerRefCount = 0;
public static HIDDeviceManager acquire(Context context) {
if (sManagerRefCount == 0) {
sManager = new HIDDeviceManager(context);
}
++sManagerRefCount;
return sManager;
}
public static void release(HIDDeviceManager manager) {
if (manager == sManager) {
--sManagerRefCount;
if (sManagerRefCount == 0) {
sManager.close();
sManager = null;
}
}
}
private Context mContext;
private HashMap<Integer, HIDDevice> mDevicesById = new HashMap<Integer, HIDDevice>();
private HashMap<UsbDevice, HIDDeviceUSB> mUSBDevices = new HashMap<UsbDevice, HIDDeviceUSB>();
private HashMap<BluetoothDevice, HIDDeviceBLESteamController> mBluetoothDevices = new HashMap<BluetoothDevice, HIDDeviceBLESteamController>();
@ -77,10 +101,40 @@ public class HIDDeviceManager {
}
};
public HIDDeviceManager(Context context) {
private HIDDeviceManager(final Context context) {
mContext = context;
HIDDeviceRegisterCallback(this);
// Make sure we have the HIDAPI library loaded with the native functions
try {
SDL.loadLibrary("hidapi");
} catch (Throwable e) {
Log.w(TAG, "Couldn't load hidapi: " + e.toString());
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setCancelable(false);
builder.setTitle("SDL HIDAPI Error");
builder.setMessage("Please report the following error to the SDL maintainers: " + e.getMessage());
builder.setNegativeButton("Quit", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
// If our context is an activity, exit rather than crashing when we can't
// call our native functions.
Activity activity = (Activity)context;
activity.finish();
}
catch (ClassCastException cce) {
// Context wasn't an activity, there's nothing we can do. Give up and return.
}
}
});
builder.show();
return;
}
HIDDeviceRegisterCallback();
mSharedPreferences = mContext.getSharedPreferences("hidapi", Context.MODE_PRIVATE);
mIsChromebook = mContext.getPackageManager().hasSystemFeature("org.chromium.arc.device_management");
@ -117,7 +171,7 @@ public class HIDDeviceManager {
return result;
}
protected void initializeUSB() {
private void initializeUSB() {
mUsbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
/*
@ -179,11 +233,15 @@ public class HIDDeviceManager {
return mUsbManager;
}
protected void shutdownUSB() {
mContext.unregisterReceiver(mUsbBroadcast);
private void shutdownUSB() {
try {
mContext.unregisterReceiver(mUsbBroadcast);
} catch (Exception e) {
// We may not have registered, that's okay
}
}
protected boolean isHIDDeviceUSB(UsbDevice usbDevice) {
private boolean isHIDDeviceUSB(UsbDevice usbDevice) {
for (int interface_number = 0; interface_number < usbDevice.getInterfaceCount(); ++interface_number) {
if (isHIDDeviceInterface(usbDevice, interface_number)) {
return true;
@ -192,7 +250,7 @@ public class HIDDeviceManager {
return false;
}
protected boolean isHIDDeviceInterface(UsbDevice usbDevice, int interface_number) {
private boolean isHIDDeviceInterface(UsbDevice usbDevice, int interface_number) {
UsbInterface usbInterface = usbDevice.getInterface(interface_number);
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_HID) {
return true;
@ -205,7 +263,7 @@ public class HIDDeviceManager {
return false;
}
protected boolean isXbox360Controller(UsbDevice usbDevice, UsbInterface usbInterface) {
private boolean isXbox360Controller(UsbDevice usbDevice, UsbInterface usbInterface) {
final int XB360_IFACE_SUBCLASS = 93;
final int XB360_IFACE_PROTOCOL = 1; // Wired only
final int[] SUPPORTED_VENDORS = {
@ -244,7 +302,7 @@ public class HIDDeviceManager {
return false;
}
protected boolean isXboxOneController(UsbDevice usbDevice, UsbInterface usbInterface) {
private boolean isXboxOneController(UsbDevice usbDevice, UsbInterface usbInterface) {
final int XB1_IFACE_SUBCLASS = 71;
final int XB1_IFACE_PROTOCOL = 208;
final int[] SUPPORTED_VENDORS = {
@ -269,13 +327,13 @@ public class HIDDeviceManager {
return false;
}
protected void handleUsbDeviceAttached(UsbDevice usbDevice) {
private void handleUsbDeviceAttached(UsbDevice usbDevice) {
if (isHIDDeviceUSB(usbDevice)) {
connectHIDDeviceUSB(usbDevice);
}
}
protected void handleUsbDeviceDetached(UsbDevice usbDevice) {
private void handleUsbDeviceDetached(UsbDevice usbDevice) {
HIDDeviceUSB device = mUSBDevices.get(usbDevice);
if (device == null)
return;
@ -287,7 +345,7 @@ public class HIDDeviceManager {
HIDDeviceDisconnected(id);
}
protected void handleUsbDevicePermission(UsbDevice usbDevice, boolean permission_granted) {
private void handleUsbDevicePermission(UsbDevice usbDevice, boolean permission_granted) {
HIDDeviceUSB device = mUSBDevices.get(usbDevice);
if (device == null)
return;
@ -299,7 +357,7 @@ public class HIDDeviceManager {
HIDDeviceOpenResult(device.getId(), opened);
}
protected void connectHIDDeviceUSB(UsbDevice usbDevice) {
private void connectHIDDeviceUSB(UsbDevice usbDevice) {
synchronized (this) {
for (int interface_number = 0; interface_number < usbDevice.getInterfaceCount(); interface_number++) {
if (isHIDDeviceInterface(usbDevice, interface_number)) {
@ -314,7 +372,7 @@ public class HIDDeviceManager {
}
}
protected void initializeBluetooth() {
private void initializeBluetooth() {
Log.d(TAG, "Initializing Bluetooth");
if (mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
@ -365,7 +423,7 @@ public class HIDDeviceManager {
}
}
protected void shutdownBluetooth() {
private void shutdownBluetooth() {
try {
mContext.unregisterReceiver(mBluetoothBroadcast);
} catch (Exception e) {
@ -464,7 +522,7 @@ public class HIDDeviceManager {
return bluetoothDevice.getName().equals("SteamController") && ((bluetoothDevice.getType() & BluetoothDevice.DEVICE_TYPE_LE) != 0);
}
public void close() {
private void close() {
shutdownUSB();
shutdownBluetooth();
synchronized (this) {
@ -504,7 +562,7 @@ public class HIDDeviceManager {
////////// JNI interface functions
//////////////////////////////////////////////////////////////////////////////////////////////////////
boolean openDevice(int deviceID) {
public boolean openDevice(int deviceID) {
// Look to see if this is a USB device and we have permission to access it
for (HIDDeviceUSB device : mUSBDevices.values()) {
if (deviceID == device.getId()) {
@ -539,7 +597,7 @@ public class HIDDeviceManager {
return false;
}
int sendOutputReport(int deviceID, byte[] report) {
public int sendOutputReport(int deviceID, byte[] report) {
try {
Log.v(TAG, "sendOutputReport deviceID=" + deviceID + " length=" + report.length);
HIDDevice device;
@ -556,7 +614,7 @@ public class HIDDeviceManager {
return -1;
}
int sendFeatureReport(int deviceID, byte[] report) {
public int sendFeatureReport(int deviceID, byte[] report) {
try {
Log.v(TAG, "sendFeatureReport deviceID=" + deviceID + " length=" + report.length);
HIDDevice device;
@ -573,7 +631,7 @@ public class HIDDeviceManager {
return -1;
}
boolean getFeatureReport(int deviceID, byte[] report) {
public boolean getFeatureReport(int deviceID, byte[] report) {
try {
Log.v(TAG, "getFeatureReport deviceID=" + deviceID);
HIDDevice device;
@ -590,7 +648,7 @@ public class HIDDeviceManager {
return false;
}
void closeDevice(int deviceID) {
public void closeDevice(int deviceID) {
try {
Log.v(TAG, "closeDevice deviceID=" + deviceID);
HIDDevice device;
@ -611,7 +669,7 @@ public class HIDDeviceManager {
/////////////// Native methods
//////////////////////////////////////////////////////////////////////////////////////////////////////
private native void HIDDeviceRegisterCallback(Object callbackHandler);
private native void HIDDeviceRegisterCallback();
private native void HIDDeviceReleaseCallback();
native void HIDDeviceConnected(int deviceID, String identifier, int vendorId, int productId, String serial_number, int release_number, String manufacturer_string, String product_string, int interface_number);

View File

@ -276,7 +276,16 @@ class HIDDeviceUSB implements HIDDevice {
int packetSize = mInputEndpoint.getMaxPacketSize();
byte[] packet = new byte[packetSize];
while (mRunning) {
int r = mConnection.bulkTransfer(mInputEndpoint, packet, packetSize, 1000);
int r;
try
{
r = mConnection.bulkTransfer(mInputEndpoint, packet, packetSize, 1000);
}
catch (Exception e)
{
Log.v(TAG, "Exception in UsbDeviceConnection bulktransfer: " + e);
break;
}
if (r < 0) {
// Could be a timeout or an I/O error
}

View File

@ -2,6 +2,8 @@ package org.libsdl.app;
import android.content.Context;
import java.lang.reflect.*;
/**
SDL library initialization
*/
@ -33,5 +35,50 @@ public class SDL {
return mContext;
}
public static void loadLibrary(String libraryName) throws UnsatisfiedLinkError, SecurityException, NullPointerException {
if (libraryName == null) {
throw new NullPointerException("No library name provided.");
}
try {
// Let's see if we have ReLinker available in the project. This is necessary for
// some projects that have huge numbers of local libraries bundled, and thus may
// trip a bug in Android's native library loader which ReLinker works around. (If
// loadLibrary works properly, ReLinker will simply use the normal Android method
// internally.)
//
// To use ReLinker, just add it as a dependency. For more information, see
// https://github.com/KeepSafe/ReLinker for ReLinker's repository.
//
Class relinkClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker");
Class relinkListenerClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker$LoadListener");
Class contextClass = mContext.getClassLoader().loadClass("android.content.Context");
Class stringClass = mContext.getClassLoader().loadClass("java.lang.String");
// Get a 'force' instance of the ReLinker, so we can ensure libraries are reinstalled if
// they've changed during updates.
Method forceMethod = relinkClass.getDeclaredMethod("force");
Object relinkInstance = forceMethod.invoke(null);
Class relinkInstanceClass = relinkInstance.getClass();
// Actually load the library!
Method loadMethod = relinkInstanceClass.getDeclaredMethod("loadLibrary", contextClass, stringClass, stringClass, relinkListenerClass);
loadMethod.invoke(relinkInstance, mContext, libraryName, null, null);
}
catch (final Throwable e) {
// Fall back
try {
System.loadLibrary(libraryName);
}
catch (final UnsatisfiedLinkError ule) {
throw ule;
}
catch (final SecurityException se) {
throw se;
}
}
}
protected static Context mContext;
}

View File

@ -154,7 +154,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
// Load the .so
public void loadLibraries() {
for (String lib : getLibraries()) {
System.loadLibrary(lib);
SDL.loadLibrary(lib);
}
}
@ -191,8 +191,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
// Setup
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.v(TAG, "Device: " + android.os.Build.DEVICE);
Log.v(TAG, "Model: " + android.os.Build.MODEL);
Log.v(TAG, "Device: " + Build.DEVICE);
Log.v(TAG, "Model: " + Build.MODEL);
Log.v(TAG, "onCreate()");
super.onCreate(savedInstanceState);
@ -250,7 +250,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
mClipboardHandler = new SDLClipboardHandler_Old();
}
mHIDDeviceManager = new HIDDeviceManager(this);
mHIDDeviceManager = HIDDeviceManager.acquire(this);
// Set up the surface
mSurface = new SDLSurface(getApplication());
@ -380,7 +380,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
Log.v(TAG, "onDestroy()");
if (mHIDDeviceManager != null) {
mHIDDeviceManager.close();
HIDDeviceManager.release(mHIDDeviceManager);
mHIDDeviceManager = null;
}
@ -520,7 +520,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
/* The native thread has finished */
public static void handleNativeExit() {
SDLActivity.mSDLThread = null;
mSingleton.finish();
if (mSingleton != null) {
mSingleton.finish();
}
}
@ -581,7 +583,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.INVISIBLE;
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.INVISIBLE;
window.getDecorView().setSystemUiVisibility(flags);
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
@ -641,7 +643,61 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
Message msg = commandHandler.obtainMessage();
msg.arg1 = command;
msg.obj = data;
return commandHandler.sendMessage(msg);
boolean result = commandHandler.sendMessage(msg);
if ((Build.VERSION.SDK_INT >= 19) && (command == COMMAND_CHANGE_WINDOW_STYLE)) {
// Ensure we don't return until the resize has actually happened,
// or 500ms have passed.
boolean bShouldWait = false;
if (data instanceof Integer) {
// Let's figure out if we're already laid out fullscreen or not.
Display display = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
android.util.DisplayMetrics realMetrics = new android.util.DisplayMetrics();
display.getRealMetrics( realMetrics );
boolean bFullscreenLayout = ((realMetrics.widthPixels == mSurface.getWidth()) &&
(realMetrics.heightPixels == mSurface.getHeight()));
if (((Integer)data).intValue() == 1) {
// If we aren't laid out fullscreen or actively in fullscreen mode already, we're going
// to change size and should wait for surfaceChanged() before we return, so the size
// is right back in native code. If we're already laid out fullscreen, though, we're
// not going to change size even if we change decor modes, so we shouldn't wait for
// surfaceChanged() -- which may not even happen -- and should return immediately.
bShouldWait = !bFullscreenLayout;
}
else {
// If we're laid out fullscreen (even if the status bar and nav bar are present),
// or are actively in fullscreen, we're going to change size and should wait for
// surfaceChanged before we return, so the size is right back in native code.
bShouldWait = bFullscreenLayout;
}
}
if (bShouldWait) {
// We'll wait for the surfaceChanged() method, which will notify us
// when called. That way, we know our current size is really the
// size we need, instead of grabbing a size that's still got
// the navigation and/or status bars before they're hidden.
//
// We'll wait for up to half a second, because some devices
// take a surprisingly long time for the surface resize, but
// then we'll just give up and return.
//
synchronized(SDLActivity.getContext()) {
try {
SDLActivity.getContext().wait(500);
}
catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
}
return result;
}
// C functions we call
@ -764,9 +820,14 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
return false;
}
// Samsung DeX mode doesn't support relative mice properly under Android 7 APIs,
// and simply returns no data under Android 8 APIs.
if (isDeXMode()) {
// DeX mode in Samsung Experience 9.0 and earlier doesn't support relative mice properly under
// Android 7 APIs, and simply returns no data under Android 8 APIs.
//
// This is fixed in Samsung Experience 9.5, which corresponds to Android 8.1.0, and
// thus SDK version 27. If we are in DeX mode and not API 27 or higher, as a result,
// we should stick to relative mode.
//
if ((Build.VERSION.SDK_INT < 27) && isDeXMode()) {
return false;
}
@ -813,6 +874,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
if (Build.MANUFACTURER.equals("MINIX") && Build.MODEL.equals("NEO-U1")) {
return true;
}
if (Build.MANUFACTURER.equals("Amlogic") && Build.MODEL.equals("X96-W")) {
return true;
}
return false;
}
@ -821,16 +885,16 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
*/
public static boolean isTablet() {
DisplayMetrics metrics = new DisplayMetrics();
Activity sdlActivity = (Activity)getContext();
sdlActivity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
Activity activity = (Activity)getContext();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
double dWidthInches = metrics.widthPixels / (double)metrics.densityDpi;
double dHeightInches = metrics.heightPixels / (double)metrics.densityDpi;
double dWidthInches = metrics.widthPixels / (double)metrics.xdpi;
double dHeightInches = metrics.heightPixels / (double)metrics.ydpi;
double dDiagonal = Math.sqrt((dWidthInches * dWidthInches) + (dHeightInches * dHeightInches));
// If our diagonal size is seven inches or greater, we consider ourselves a tablet.
return (dDiagonal > 7.0);
return (dDiagonal >= 7.0);
}
/**
@ -1505,6 +1569,10 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
int format, int width, int height) {
Log.v("SDL", "surfaceChanged()");
if (SDLActivity.mSingleton == null) {
return;
}
int sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565 by default
switch (format) {
case PixelFormat.A_8:
@ -1552,25 +1620,28 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
mWidth = width;
mHeight = height;
int nDeviceWidth = width;
int nDeviceHeight = height;
try
{
if ( android.os.Build.VERSION.SDK_INT >= 17 )
{
android.util.DisplayMetrics realMetrics = new android.util.DisplayMetrics();
mDisplay.getRealMetrics( realMetrics );
nDeviceWidth = realMetrics.widthPixels;
nDeviceHeight = realMetrics.heightPixels;
}
}
catch ( java.lang.Throwable throwable ) {}
int nDeviceWidth = width;
int nDeviceHeight = height;
try
{
if (Build.VERSION.SDK_INT >= 17) {
android.util.DisplayMetrics realMetrics = new android.util.DisplayMetrics();
mDisplay.getRealMetrics( realMetrics );
nDeviceWidth = realMetrics.widthPixels;
nDeviceHeight = realMetrics.heightPixels;
}
}
catch ( java.lang.Throwable throwable ) {}
Log.v("SDL", "Window size: " + width + "x" + height);
Log.v("SDL", "Device size: " + nDeviceWidth + "x" + nDeviceHeight);
synchronized(SDLActivity.getContext()) {
// In case we're waiting on a size change after going fullscreen, send a notification.
SDLActivity.getContext().notifyAll();
}
Log.v("SDL", "Window size: " + width + "x" + height);
Log.v("SDL", "Device size: " + nDeviceWidth + "x" + nDeviceHeight);
SDLActivity.onNativeResize(width, height, nDeviceWidth, nDeviceHeight, sdlFormat, mDisplay.getRefreshRate());
boolean skip = false;
int requestedOrientation = SDLActivity.mSingleton.getRequestedOrientation();

View File

@ -1,6 +1,7 @@
package org.libsdl.app;
import android.media.*;
import android.os.Build;
import android.util.Log;
public class SDLAudioManager
@ -17,41 +18,250 @@ public class SDLAudioManager
// Audio
/**
* This method is called by SDL using JNI.
*/
public static int audioOpen(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
protected static String getAudioFormatString(int audioFormat) {
switch (audioFormat) {
case AudioFormat.ENCODING_PCM_8BIT:
return "8-bit";
case AudioFormat.ENCODING_PCM_16BIT:
return "16-bit";
case AudioFormat.ENCODING_PCM_FLOAT:
return "float";
default:
return Integer.toString(audioFormat);
}
}
Log.v(TAG, "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
protected static int[] open(boolean isCapture, int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) {
int channelConfig;
int sampleSize;
int frameSize;
Log.v(TAG, "Opening " + (isCapture ? "capture" : "playback") + ", requested " + desiredFrames + " frames of " + desiredChannels + " channel " + getAudioFormatString(audioFormat) + " audio at " + sampleRate + " Hz");
/* On older devices let's use known good settings */
if (Build.VERSION.SDK_INT < 21) {
if (desiredChannels > 2) {
desiredChannels = 2;
}
if (sampleRate < 8000) {
sampleRate = 8000;
} else if (sampleRate > 48000) {
sampleRate = 48000;
}
}
if (audioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
int minSDKVersion = (isCapture ? 23 : 21);
if (Build.VERSION.SDK_INT < minSDKVersion) {
audioFormat = AudioFormat.ENCODING_PCM_16BIT;
}
}
switch (audioFormat)
{
case AudioFormat.ENCODING_PCM_8BIT:
sampleSize = 1;
break;
case AudioFormat.ENCODING_PCM_16BIT:
sampleSize = 2;
break;
case AudioFormat.ENCODING_PCM_FLOAT:
sampleSize = 4;
break;
default:
Log.v(TAG, "Requested format " + audioFormat + ", getting ENCODING_PCM_16BIT");
audioFormat = AudioFormat.ENCODING_PCM_16BIT;
sampleSize = 2;
break;
}
if (isCapture) {
switch (desiredChannels) {
case 1:
channelConfig = AudioFormat.CHANNEL_IN_MONO;
break;
case 2:
channelConfig = AudioFormat.CHANNEL_IN_STEREO;
break;
default:
Log.v(TAG, "Requested " + desiredChannels + " channels, getting stereo");
desiredChannels = 2;
channelConfig = AudioFormat.CHANNEL_IN_STEREO;
break;
}
} else {
switch (desiredChannels) {
case 1:
channelConfig = AudioFormat.CHANNEL_OUT_MONO;
break;
case 2:
channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
break;
case 3:
channelConfig = AudioFormat.CHANNEL_OUT_STEREO | AudioFormat.CHANNEL_OUT_FRONT_CENTER;
break;
case 4:
channelConfig = AudioFormat.CHANNEL_OUT_QUAD;
break;
case 5:
channelConfig = AudioFormat.CHANNEL_OUT_QUAD | AudioFormat.CHANNEL_OUT_FRONT_CENTER;
break;
case 6:
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1;
break;
case 7:
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1 | AudioFormat.CHANNEL_OUT_BACK_CENTER;
break;
case 8:
if (Build.VERSION.SDK_INT >= 23) {
channelConfig = AudioFormat.CHANNEL_OUT_7POINT1_SURROUND;
} else {
Log.v(TAG, "Requested " + desiredChannels + " channels, getting 5.1 surround");
desiredChannels = 6;
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1;
}
break;
default:
Log.v(TAG, "Requested " + desiredChannels + " channels, getting stereo");
desiredChannels = 2;
channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
break;
}
/*
Log.v(TAG, "Speaker configuration (and order of channels):");
if ((channelConfig & 0x00000004) != 0) {
Log.v(TAG, " CHANNEL_OUT_FRONT_LEFT");
}
if ((channelConfig & 0x00000008) != 0) {
Log.v(TAG, " CHANNEL_OUT_FRONT_RIGHT");
}
if ((channelConfig & 0x00000010) != 0) {
Log.v(TAG, " CHANNEL_OUT_FRONT_CENTER");
}
if ((channelConfig & 0x00000020) != 0) {
Log.v(TAG, " CHANNEL_OUT_LOW_FREQUENCY");
}
if ((channelConfig & 0x00000040) != 0) {
Log.v(TAG, " CHANNEL_OUT_BACK_LEFT");
}
if ((channelConfig & 0x00000080) != 0) {
Log.v(TAG, " CHANNEL_OUT_BACK_RIGHT");
}
if ((channelConfig & 0x00000100) != 0) {
Log.v(TAG, " CHANNEL_OUT_FRONT_LEFT_OF_CENTER");
}
if ((channelConfig & 0x00000200) != 0) {
Log.v(TAG, " CHANNEL_OUT_FRONT_RIGHT_OF_CENTER");
}
if ((channelConfig & 0x00000400) != 0) {
Log.v(TAG, " CHANNEL_OUT_BACK_CENTER");
}
if ((channelConfig & 0x00000800) != 0) {
Log.v(TAG, " CHANNEL_OUT_SIDE_LEFT");
}
if ((channelConfig & 0x00001000) != 0) {
Log.v(TAG, " CHANNEL_OUT_SIDE_RIGHT");
}
*/
}
frameSize = (sampleSize * desiredChannels);
// Let the user pick a larger buffer if they really want -- but ye
// gods they probably shouldn't, the minimums are horrifyingly high
// latency already
desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
int minBufferSize;
if (isCapture) {
minBufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
} else {
minBufferSize = AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat);
}
desiredFrames = Math.max(desiredFrames, (minBufferSize + frameSize - 1) / frameSize);
if (mAudioTrack == null) {
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
int[] results = new int[4];
// Instantiating AudioTrack can "succeed" without an exception and the track may still be invalid
// Ref: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/AudioTrack.java
// Ref: http://developer.android.com/reference/android/media/AudioTrack.html#getState()
if (isCapture) {
if (mAudioRecord == null) {
mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, sampleRate,
channelConfig, audioFormat, desiredFrames * frameSize);
if (mAudioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
Log.e(TAG, "Failed during initialization of Audio Track");
mAudioTrack = null;
return -1;
// see notes about AudioTrack state in audioOpen(), above. Probably also applies here.
if (mAudioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
Log.e(TAG, "Failed during initialization of AudioRecord");
mAudioRecord.release();
mAudioRecord = null;
return null;
}
mAudioRecord.startRecording();
}
mAudioTrack.play();
results[0] = mAudioRecord.getSampleRate();
results[1] = mAudioRecord.getAudioFormat();
results[2] = mAudioRecord.getChannelCount();
results[3] = desiredFrames;
} else {
if (mAudioTrack == null) {
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
// Instantiating AudioTrack can "succeed" without an exception and the track may still be invalid
// Ref: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/AudioTrack.java
// Ref: http://developer.android.com/reference/android/media/AudioTrack.html#getState()
if (mAudioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
/* Try again, with safer values */
Log.e(TAG, "Failed during initialization of Audio Track");
mAudioTrack.release();
mAudioTrack = null;
return null;
}
mAudioTrack.play();
}
results[0] = mAudioTrack.getSampleRate();
results[1] = mAudioTrack.getAudioFormat();
results[2] = mAudioTrack.getChannelCount();
results[3] = desiredFrames;
}
Log.v(TAG, "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
Log.v(TAG, "Opening " + (isCapture ? "capture" : "playback") + ", got " + results[3] + " frames of " + results[2] + " channel " + getAudioFormatString(results[1]) + " audio at " + results[0] + " Hz");
return 0;
return results;
}
/**
* This method is called by SDL using JNI.
*/
public static int[] audioOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) {
return open(false, sampleRate, audioFormat, desiredChannels, desiredFrames);
}
/**
* This method is called by SDL using JNI.
*/
public static void audioWriteFloatBuffer(float[] buffer) {
if (mAudioTrack == null) {
Log.e(TAG, "Attempted to make audio call with uninitialized audio!");
return;
}
for (int i = 0; i < buffer.length;) {
int result = mAudioTrack.write(buffer, i, buffer.length - i, AudioTrack.WRITE_BLOCKING);
if (result > 0) {
i += result;
} else if (result == 0) {
try {
Thread.sleep(1);
} catch(InterruptedException e) {
// Nom nom
}
} else {
Log.w(TAG, "SDL audio: error return from write(float)");
return;
}
}
}
/**
@ -63,7 +273,7 @@ public class SDLAudioManager
return;
}
for (int i = 0; i < buffer.length; ) {
for (int i = 0; i < buffer.length;) {
int result = mAudioTrack.write(buffer, i, buffer.length - i);
if (result > 0) {
i += result;
@ -109,53 +319,33 @@ public class SDLAudioManager
/**
* This method is called by SDL using JNI.
*/
public static int captureOpen(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
public static int[] captureOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) {
return open(true, sampleRate, audioFormat, desiredChannels, desiredFrames);
}
Log.v(TAG, "SDL capture: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
// Let the user pick a larger buffer if they really want -- but ye
// gods they probably shouldn't, the minimums are horrifyingly high
// latency already
desiredFrames = Math.max(desiredFrames, (AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
if (mAudioRecord == null) {
mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, sampleRate,
channelConfig, audioFormat, desiredFrames * frameSize);
// see notes about AudioTrack state in audioOpen(), above. Probably also applies here.
if (mAudioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
Log.e(TAG, "Failed during initialization of AudioRecord");
mAudioRecord.release();
mAudioRecord = null;
return -1;
}
mAudioRecord.startRecording();
}
Log.v(TAG, "SDL capture: got " + ((mAudioRecord.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioRecord.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioRecord.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
return 0;
/** This method is called by SDL using JNI. */
public static int captureReadFloatBuffer(float[] buffer, boolean blocking) {
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
}
/** This method is called by SDL using JNI. */
public static int captureReadShortBuffer(short[] buffer, boolean blocking) {
// !!! FIXME: this is available in API Level 23. Until then, we always block. :(
//return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
return mAudioRecord.read(buffer, 0, buffer.length);
if (Build.VERSION.SDK_INT < 23) {
return mAudioRecord.read(buffer, 0, buffer.length);
} else {
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
}
}
/** This method is called by SDL using JNI. */
public static int captureReadByteBuffer(byte[] buffer, boolean blocking) {
// !!! FIXME: this is available in API Level 23. Until then, we always block. :(
//return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
return mAudioRecord.read(buffer, 0, buffer.length);
if (Build.VERSION.SDK_INT < 23) {
return mAudioRecord.read(buffer, 0, buffer.length);
} else {
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
}
}
/** This method is called by SDL using JNI. */
public static void audioClose() {
if (mAudioTrack != null) {

View File

@ -11,7 +11,7 @@ import android.view.*;
import android.util.Log;
public class SDLControllerManager
public class SDLControllerManager
{
public static native int nativeSetupJNI();
@ -36,23 +36,25 @@ public class SDLControllerManager
private static final String TAG = "SDLControllerManager";
public static void initialize() {
mJoystickHandler = null;
mHapticHandler = null;
SDLControllerManager.setup();
}
public static void setup() {
if (Build.VERSION.SDK_INT >= 19) {
mJoystickHandler = new SDLJoystickHandler_API19();
} else if (Build.VERSION.SDK_INT >= 16) {
mJoystickHandler = new SDLJoystickHandler_API16();
} else if (Build.VERSION.SDK_INT >= 12) {
mJoystickHandler = new SDLJoystickHandler_API12();
} else {
mJoystickHandler = new SDLJoystickHandler();
if (mJoystickHandler == null) {
if (Build.VERSION.SDK_INT >= 19) {
mJoystickHandler = new SDLJoystickHandler_API19();
} else if (Build.VERSION.SDK_INT >= 16) {
mJoystickHandler = new SDLJoystickHandler_API16();
} else if (Build.VERSION.SDK_INT >= 12) {
mJoystickHandler = new SDLJoystickHandler_API12();
} else {
mJoystickHandler = new SDLJoystickHandler();
}
}
if (mHapticHandler == null) {
if (Build.VERSION.SDK_INT >= 26) {
mHapticHandler = new SDLHapticHandler_API26();
} else {
mHapticHandler = new SDLHapticHandler();
}
}
mHapticHandler = new SDLHapticHandler();
}
// Joystick glue code, just a series of stubs that redirect to the SDLJoystickHandler instance
@ -77,8 +79,8 @@ public class SDLControllerManager
/**
* This method is called by SDL using JNI.
*/
public static void hapticRun(int device_id, int length) {
mHapticHandler.run(device_id, length);
public static void hapticRun(int device_id, float intensity, int length) {
mHapticHandler.run(device_id, intensity, length);
}
/**
@ -409,6 +411,38 @@ class SDLJoystickHandler_API19 extends SDLJoystickHandler_API16 {
}
}
class SDLHapticHandler_API26 extends SDLHapticHandler {
@Override
public void run(int device_id, float intensity, int length) {
SDLHaptic haptic = getHaptic(device_id);
if (haptic != null) {
Log.d("SDL", "Rtest: Vibe with intensity " + intensity + " for " + length);
if (intensity == 0.0f) {
stop(device_id);
return;
}
int vibeValue = Math.round(intensity * 255);
if (vibeValue > 255) {
vibeValue = 255;
}
if (vibeValue < 1) {
stop(device_id);
return;
}
try {
haptic.vib.vibrate(VibrationEffect.createOneShot(length, vibeValue));
}
catch (Exception e) {
// Fall back to the generic method, which uses DEFAULT_AMPLITUDE, but works even if
// something went horribly wrong with the Android 8.0 APIs.
haptic.vib.vibrate(length);
}
}
}
}
class SDLHapticHandler {
class SDLHaptic {
@ -418,15 +452,15 @@ class SDLHapticHandler {
}
private ArrayList<SDLHaptic> mHaptics;
public SDLHapticHandler() {
mHaptics = new ArrayList<SDLHaptic>();
}
public void run(int device_id, int length) {
public void run(int device_id, float intensity, int length) {
SDLHaptic haptic = getHaptic(device_id);
if (haptic != null) {
haptic.vib.vibrate (length);
haptic.vib.vibrate(length);
}
}
@ -438,7 +472,7 @@ class SDLHapticHandler {
}
public void pollHapticDevices() {
final int deviceId_VIBRATOR_SERVICE = 999999;
boolean hasVibratorService = false;
@ -482,7 +516,7 @@ class SDLHapticHandler {
haptic = new SDLHaptic();
haptic.device_id = deviceId_VIBRATOR_SERVICE;
haptic.name = "VIBRATOR_SERVICE";
haptic.vib = vib;
haptic.vib = vib;
mHaptics.add(haptic);
SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name);
}
@ -524,7 +558,7 @@ class SDLHapticHandler {
}
}
return null;
}
}
}
class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener {
@ -614,7 +648,7 @@ class SDLGenericMotionListener_API24 extends SDLGenericMotionListener_API12 {
case InputDevice.SOURCE_GAMEPAD:
case InputDevice.SOURCE_DPAD:
return SDLControllerManager.handleJoystickMotionEvent(event);
case InputDevice.SOURCE_MOUSE:
if (!SDLActivity.mSeparateMouseAndTouch) {
break;
@ -705,7 +739,7 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
case InputDevice.SOURCE_GAMEPAD:
case InputDevice.SOURCE_DPAD:
return SDLControllerManager.handleJoystickMotionEvent(event);
case InputDevice.SOURCE_MOUSE:
case 12290: // DeX desktop mouse cursor is a separate non-standard input type.
if (!SDLActivity.mSeparateMouseAndTouch) {
@ -764,7 +798,7 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
@Override
public boolean supportsRelativeMouse() {
return !SDLActivity.isDeXMode();
return (!SDLActivity.isDeXMode() || (Build.VERSION.SDK_INT >= 27));
}
@Override
@ -774,17 +808,17 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
@Override
public boolean setRelativeMouseEnabled(boolean enabled) {
if (!SDLActivity.isDeXMode()) {
if (!SDLActivity.isDeXMode() || (Build.VERSION.SDK_INT >= 27)) {
if (enabled) {
SDLActivity.getContentView().requestPointerCapture();
}
else {
SDLActivity.getContentView().releasePointerCapture();
SDLActivity.getContentView().releasePointerCapture();
}
mRelativeModeEnabled = enabled;
return true;
}
else
else
{
return false;
}

View File

@ -3,9 +3,10 @@
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.android.tools.build:gradle:3.2.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@ -15,6 +16,7 @@ buildscript {
allprojects {
repositories {
jcenter()
google()
}
}

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip

View File

@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2005-02-02.21
scriptversion=2011-11-20.07; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
@ -35,42 +35,72 @@ scriptversion=2005-02-02.21
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# put in absolute paths if you don't have them in your path; or use env. vars.
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chmodcmd="$chmodprog 0755"
chowncmd=
chgrpcmd=
stripcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
mvcmd="$mvprog"
stripcmd=
src=
dst=
dir_arg=
dstarg=
dst_arg=
copy_on_change=false
no_target_directory=
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
@ -80,108 +110,148 @@ In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
-c (ignored)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
--help display this help and exit.
--version display version info and exit.
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test -n "$1"; do
while test $# -ne 0; do
case $1 in
-c) shift
continue;;
-c) ;;
-d) dir_arg=true
shift
continue;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
shift;;
--help) echo "$usage"; exit $?;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
shift;;
-s) stripcmd=$stripprog
shift
continue;;
-s) stripcmd=$stripprog;;
-t) dstarg=$2
shift
shift
continue;;
-t) dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) no_target_directory=true
shift
continue;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
*) # When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
test -n "$dir_arg$dstarg" && break
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dstarg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dstarg"
shift # fnord
fi
shift # arg
dstarg=$arg
done
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test -z "$1"; then
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names starting with `-'.
# Protect names problematic for 'test' and other utilities.
case $src in
-*) src=./$src ;;
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
src=
if test -d "$dst"; then
mkdircmd=:
chmodcmd=
else
mkdircmd=$mkdirprog
fi
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
@ -190,71 +260,194 @@ do
exit 1
fi
if test -z "$dstarg"; then
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dstarg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst ;;
esac
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dstarg: Is a directory" >&2
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dst=$dst/`basename "$src"`
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
# This sed command emulates the dirname command.
dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
obsolete_mkdir_used=false
# Make sure that the destination directory exists.
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
# Skip lots of stat calls in the usual case.
if test ! -d "$dstdir"; then
defaultIFS='
'
IFS="${IFS-$defaultIFS}"
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
oIFS=$IFS
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
shift
IFS=$oIFS
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
pathcomp=
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
while test $# -ne 0 ; do
pathcomp=$pathcomp$1
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
if test ! -d "$pathcomp"; then
$mkdirprog "$pathcomp"
# mkdir can fail with a `File exist' error in case several
# install-sh are creating the directory concurrently. This
# is OK.
test -d "$pathcomp" || exit
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
pathcomp=$pathcomp/
done
fi
fi
if test -n "$dir_arg"; then
$doit $mkdircmd "$dst" \
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
dstfile=`basename "$dst"`
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
@ -262,10 +455,9 @@ do
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
trap '(exit $?); exit' 1 2 13 15
# Copy the file name to the temp name.
$doit $cpprog "$src" "$dsttmp" &&
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
@ -273,51 +465,63 @@ do
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# Now rename the file to the real destination.
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
|| {
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
if test -f "$dstdir/$dstfile"; then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|| {
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit 1
}
else
:
fi
} &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
}
}
fi || { (exit 1); exit 1; }
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit 0
}
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View File

@ -1,29 +1,59 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
scriptversion=2009-04-28.21; # UTC
# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain.
#
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
IFS=" "" $nl"
errstatus=0
dirmode=""
dirmode=
usage="\
Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
Create each directory DIR (with mode MODE, if specified), including all
leading file name components.
Report bugs to <bug-automake@gnu.org>."
# process command line arguments
while test $# -gt 0 ; do
case "${1}" in
-h | --help | --h* ) # -h for help
echo "${usage}" 1>&2; exit 0 ;;
-m ) # -m PERM arg
shift
test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
dirmode="${1}"
shift ;;
-- ) shift; break ;; # stop option processing
-* ) echo "${usage}" 1>&2; exit 1 ;; # unknown option
* ) break ;; # first non-opt arg
esac
case $1 in
-h | --help | --h*) # -h for help
echo "$usage"
exit $?
;;
-m) # -m PERM arg
shift
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
dirmode=$1
shift
;;
--version)
echo "$0 $scriptversion"
exit $?
;;
--) # stop option processing
shift
break
;;
-*) # unknown option
echo "$usage" 1>&2
exit 1
;;
*) # first non-opt arg
break
;;
esac
done
for file
@ -36,64 +66,97 @@ do
done
case $# in
0) exit 0 ;;
0) exit 0 ;;
esac
# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
# mkdir -p a/c at the same time, both will detect that a is missing,
# one will create a, then the other will try to create a and die with
# a "File exists" error. This is a problem when calling mkinstalldirs
# from a parallel make. We use --version in the probe to restrict
# ourselves to GNU mkdir, which is thread-safe.
case $dirmode in
'')
if mkdir -p -- . 2>/dev/null; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
fi ;;
*)
if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
fi ;;
'')
if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
else
# On NextStep and OpenStep, the 'mkdir' command does not
# recognize any option. It will interpret all options as
# directories to create, and then abort because '.' already
# exists.
test -d ./-p && rmdir ./-p
test -d ./--version && rmdir ./--version
fi
;;
*)
if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
test ! -d ./--version; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
else
# Clean up after NextStep and OpenStep mkdir.
for d in ./-m ./-p ./--version "./$dirmode";
do
test -d $d && rmdir $d
done
fi
;;
esac
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
case $file in
/*) pathcomp=/ ;;
*) pathcomp= ;;
esac
oIFS=$IFS
IFS=/
set fnord $file
shift
IFS=$oIFS
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
for d
do
test "x$d" = x && continue
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
pathcomp=$pathcomp$d
case $pathcomp in
-*) pathcomp=./$pathcomp ;;
esac
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
mkdir "$pathcomp" || lasterr=$?
lasterr=""
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
fi
fi
fi
fi
pathcomp="$pathcomp/"
done
pathcomp=$pathcomp/
done
done
exit $errstatus
# Local Variables:
# mode: shell-script
# sh-indentation: 3
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
# mkinstalldirs ends here

View File

@ -39,7 +39,7 @@
#
# Base version of SDL, used for packaging purposes
$SDLVersion = "2.0.7"
$SDLVersion = "2.0.9"
# Gets the .bat file that sets up an MSBuild environment, given one of
# Visual Studio's, "PlatformToolset"s.

79
configure vendored
View File

@ -2719,9 +2719,9 @@ orig_CFLAGS="$CFLAGS"
#
SDL_MAJOR_VERSION=2
SDL_MINOR_VERSION=0
SDL_MICRO_VERSION=8
SDL_MICRO_VERSION=9
SDL_INTERFACE_AGE=0
SDL_BINARY_AGE=8
SDL_BINARY_AGE=9
SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
@ -23165,20 +23165,6 @@ if test "x$ac_cv_header_xinput_h" = xyes; then :
fi
ac_fn_c_check_header_mongrel "$LINENO" "mmdeviceapi.h" "ac_cv_header_mmdeviceapi_h" "$ac_includes_default"
if test "x$ac_cv_header_mmdeviceapi_h" = xyes; then :
have_wasapi=yes
fi
ac_fn_c_check_header_mongrel "$LINENO" "audioclient.h" "ac_cv_header_audioclient_h" "$ac_includes_default"
if test "x$ac_cv_header_audioclient_h" = xyes; then :
else
have_wasapi=no
fi
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@ -23257,14 +23243,6 @@ $as_echo "#define HAVE_XINPUT_STATE_EX 1" >>confdefs.h
SUMMARY_video="${SUMMARY_video} directx"
SUMMARY_audio="${SUMMARY_audio} directx"
# Check whether --enable-wasapi was given.
if test "${enable_wasapi+set}" = set; then :
enableval=$enable_wasapi;
else
enable_wasapi=yes
fi
# FIXME: latest Cygwin finds dinput headers, but we die on other win32 headers.
# FIXME: ...so force it off for now.
case "$host" in
@ -23273,6 +23251,45 @@ fi
;;
esac
fi
ac_fn_c_check_header_mongrel "$LINENO" "mmdeviceapi.h" "ac_cv_header_mmdeviceapi_h" "$ac_includes_default"
if test "x$ac_cv_header_mmdeviceapi_h" = xyes; then :
have_wasapi=yes
fi
if test x$have_wasapi = xyes; then
$as_echo "#define HAVE_MMDEVICEAPI_H 1" >>confdefs.h
fi
ac_fn_c_check_header_mongrel "$LINENO" "audioclient.h" "ac_cv_header_audioclient_h" "$ac_includes_default"
if test "x$ac_cv_header_audioclient_h" = xyes; then :
else
have_wasapi=no
fi
if test x$have_wasapi = xyes; then
$as_echo "#define HAVE_AUDIOCLIENT_H 1" >>confdefs.h
fi
ac_fn_c_check_header_mongrel "$LINENO" "endpointvolume.h" "ac_cv_header_endpointvolume_h" "$ac_includes_default"
if test "x$ac_cv_header_endpointvolume_h" = xyes; then :
$as_echo "#define HAVE_ENDPOINTVOLUME_H 1" >>confdefs.h
fi
# Check whether --enable-wasapi was given.
if test "${enable_wasapi+set}" = set; then :
enableval=$enable_wasapi;
else
enable_wasapi=yes
fi
}
CheckDLOPEN()
@ -24296,7 +24313,13 @@ $as_echo "#define SDL_JOYSTICK_DINPUT 1" >>confdefs.h
$as_echo "#define SDL_JOYSTICK_WINMM 1" >>confdefs.h
fi
$as_echo "#define SDL_JOYSTICK_HIDAPI 1" >>confdefs.h
SOURCES="$SOURCES $srcdir/src/joystick/windows/*.c"
SOURCES="$SOURCES $srcdir/src/joystick/hidapi/*.c"
SOURCES="$SOURCES $srcdir/src/hidapi/windows/hid.c"
EXTRA_CFLAGS="$EXTRA_CFLAGS -I$srcdir/src/hidapi/hidapi"
have_joystick=yes
fi
if test x$enable_haptic = xyes; then
@ -24360,7 +24383,7 @@ $as_echo "#define SDL_LOADSO_WINDOWS 1" >>confdefs.h
else
LIBUUID=-luuid
fi
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion $LIBUUID -static-libgcc"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion $LIBUUID -static-libgcc"
# The Windows platform requires special setup
VERSION_SOURCES="$srcdir/src/main/windows/*.rc"
SDLMAIN_SOURCES="$srcdir/src/main/windows/*.c"
@ -24796,7 +24819,7 @@ esac
if test x$have_joystick != xyes; then
if test x$enable_joystick = xyes; then
$as_echo "#define SDL_JOYSTICK_DISABLED 1" >>confdefs.h
$as_echo "#define SDL_JOYSTICK_DUMMY 1" >>confdefs.h
fi
SOURCES="$SOURCES $srcdir/src/joystick/dummy/*.c"
@ -24804,7 +24827,7 @@ fi
if test x$have_haptic != xyes; then
if test x$enable_haptic = xyes; then
$as_echo "#define SDL_HAPTIC_DISABLED 1" >>confdefs.h
$as_echo "#define SDL_HAPTIC_DUMMY 1" >>confdefs.h
fi
SOURCES="$SOURCES $srcdir/src/haptic/dummy/*.c"
@ -24812,7 +24835,7 @@ fi
if test x$have_sensor != xyes; then
if test x$enable_sensor = xyes; then
$as_echo "#define SDL_SENSOR_DISABLED 1" >>confdefs.h
$as_echo "#define SDL_SENSOR_DUMMY 1" >>confdefs.h
fi
SOURCES="$SOURCES $srcdir/src/sensor/dummy/*.c"

View File

@ -20,9 +20,9 @@ dnl Set various version strings - taken gratefully from the GTk sources
#
SDL_MAJOR_VERSION=2
SDL_MINOR_VERSION=0
SDL_MICRO_VERSION=8
SDL_MICRO_VERSION=9
SDL_INTERFACE_AGE=0
SDL_BINARY_AGE=8
SDL_BINARY_AGE=9
SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
AC_SUBST(SDL_MAJOR_VERSION)
@ -3052,8 +3052,6 @@ AC_HELP_STRING([--enable-directx], [use DirectX for Windows audio/video [[defaul
AC_CHECK_HEADER(dinput.h, have_dinput=yes)
AC_CHECK_HEADER(dxgi.h, have_dxgi=yes)
AC_CHECK_HEADER(xinput.h, have_xinput=yes)
AC_CHECK_HEADER(mmdeviceapi.h, have_wasapi=yes)
AC_CHECK_HEADER(audioclient.h,,have_wasapi=no)
AC_TRY_COMPILE([
#include <windows.h>
#include <xinput.h>
@ -3090,10 +3088,6 @@ XINPUT_STATE_EX s1;
SUMMARY_video="${SUMMARY_video} directx"
SUMMARY_audio="${SUMMARY_audio} directx"
AC_ARG_ENABLE(wasapi,
AC_HELP_STRING([--enable-wasapi], [use the Windows WASAPI audio driver [[default=yes]]]),
, enable_wasapi=yes)
# FIXME: latest Cygwin finds dinput headers, but we die on other win32 headers.
# FIXME: ...so force it off for now.
case "$host" in
@ -3102,6 +3096,21 @@ AC_HELP_STRING([--enable-wasapi], [use the Windows WASAPI audio driver [[default
;;
esac
fi
AC_CHECK_HEADER(mmdeviceapi.h, have_wasapi=yes)
if test x$have_wasapi = xyes; then
AC_DEFINE(HAVE_MMDEVICEAPI_H,1,[])
fi
AC_CHECK_HEADER(audioclient.h,,have_wasapi=no)
if test x$have_wasapi = xyes; then
AC_DEFINE(HAVE_AUDIOCLIENT_H,1,[])
fi
AC_CHECK_HEADER(endpointvolume.h,AC_DEFINE(HAVE_ENDPOINTVOLUME_H,1,[]))
AC_ARG_ENABLE(wasapi,
AC_HELP_STRING([--enable-wasapi], [use the Windows WASAPI audio driver [[default=yes]]]),
, enable_wasapi=yes)
}
dnl Check for the dlfcn.h interface for dynamically loading objects
@ -3628,7 +3637,11 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
else
AC_DEFINE(SDL_JOYSTICK_WINMM, 1, [ ])
fi
AC_DEFINE(SDL_JOYSTICK_HIDAPI, 1, [ ])
SOURCES="$SOURCES $srcdir/src/joystick/windows/*.c"
SOURCES="$SOURCES $srcdir/src/joystick/hidapi/*.c"
SOURCES="$SOURCES $srcdir/src/hidapi/windows/hid.c"
EXTRA_CFLAGS="$EXTRA_CFLAGS -I$srcdir/src/hidapi/hidapi"
have_joystick=yes
fi
if test x$enable_haptic = xyes; then
@ -3678,7 +3691,7 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
else
LIBUUID=-luuid
fi
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion $LIBUUID -static-libgcc"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion $LIBUUID -static-libgcc"
# The Windows platform requires special setup
VERSION_SOURCES="$srcdir/src/main/windows/*.rc"
SDLMAIN_SOURCES="$srcdir/src/main/windows/*.c"
@ -3999,19 +4012,19 @@ esac
if test x$have_joystick != xyes; then
if test x$enable_joystick = xyes; then
AC_DEFINE(SDL_JOYSTICK_DISABLED, 1, [ ])
AC_DEFINE(SDL_JOYSTICK_DUMMY, 1, [ ])
fi
SOURCES="$SOURCES $srcdir/src/joystick/dummy/*.c"
fi
if test x$have_haptic != xyes; then
if test x$enable_haptic = xyes; then
AC_DEFINE(SDL_HAPTIC_DISABLED, 1, [ ])
AC_DEFINE(SDL_HAPTIC_DUMMY, 1, [ ])
fi
SOURCES="$SOURCES $srcdir/src/haptic/dummy/*.c"
fi
if test x$have_sensor != xyes; then
if test x$enable_sensor = xyes; then
AC_DEFINE(SDL_SENSOR_DISABLED, 1, [ ])
AC_DEFINE(SDL_SENSOR_DUMMY, 1, [ ])
fi
SOURCES="$SOURCES $srcdir/src/sensor/dummy/*.c"
fi

6
debian/changelog vendored
View File

@ -1,3 +1,9 @@
libsdl2 (2.0.9) UNRELEASED; urgency=low
* Updated SDL to version 2.0.9
-- Sam Lantinga <slouken@libsdl.org> Wed, 26 Sep 2018 10:02:21 -0800
libsdl2 (2.0.8) UNRELEASED; urgency=low
* Updated SDL to version 2.0.8

View File

@ -77,18 +77,16 @@ For more complex projects, follow these instructions:
and rename it to the name of your project.
2. Move or symlink this SDL directory into the "<project>/app/jni" directory
3. Edit "<project>/app/jni/src/Android.mk" to include your source files
4. Run 'ndk-build' (a script provided by the NDK). This compiles the C source
If you want to use Android Studio (recommended), skip to the Android Studio section below.
4a. If you want to use Android Studio, simply open your <project> directory and start building.
5. Run './gradlew installDebug' in the project directory. This compiles the .java, creates an .apk with the native code embedded, and installs it on any connected Android device
4b. If you want to build manually, run './gradlew installDebug' in the project directory. This compiles the .java, creates an .apk with the native code embedded, and installs it on any connected Android device
Here's an explanation of the files in the Android project, so you can customize them:
android-project/app
build.gradle - build info including the application version and SDK
src/main/AndroidManifest.xml - package manifest. Among others, it contains the class name
of the main Activity and the package name of the application.
src/main/AndroidManifest.xml - package manifest. Among others, it contains the class name of the main Activity and the package name of the application.
jni/ - directory holding native code
jni/Application.mk - Application JNI settings, including target platform and STL library
jni/Android.mk - Android makefile that can call recursively the Android.mk files in all subdirectories
@ -216,26 +214,10 @@ detach it.
You can use STL in your project by creating an Application.mk file in the jni
folder and adding the following line:
APP_STL := stlport_static
APP_STL := c++_shared
For more information check out CPLUSPLUS-SUPPORT.html in the NDK documentation.
================================================================================
Additional documentation
================================================================================
The documentation in the NDK docs directory is very helpful in understanding the
build process and how to work with native code on the Android platform.
The best place to start is with docs/OVERVIEW.TXT
================================================================================
Using Android Studio
================================================================================
You can open your project directory with Android Studio and run it normally.
For more information go here:
https://developer.android.com/ndk/guides/cpp-support
================================================================================
@ -291,7 +273,10 @@ You can see the complete command line that ndk-build is using by passing V=1 on
ndk-build V=1
If your application crashes in native code, you can use addr2line to convert the
If your application crashes in native code, you can use ndk-stack to get a symbolic stack trace:
https://developer.android.com/ndk/guides/ndk-stack
If you want to go through the process manually, you can use addr2line to convert the
addresses in the stack trace to lines in your code.
For example, if your crash looks like this:

View File

@ -140,7 +140,8 @@ typedef Uint16 SDL_AudioFormat;
#define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE 0x00000001
#define SDL_AUDIO_ALLOW_FORMAT_CHANGE 0x00000002
#define SDL_AUDIO_ALLOW_CHANNELS_CHANGE 0x00000004
#define SDL_AUDIO_ALLOW_ANY_CHANGE (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE)
#define SDL_AUDIO_ALLOW_SAMPLES_CHANGE 0x00000008
#define SDL_AUDIO_ALLOW_ANY_CHANGE (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE|SDL_AUDIO_ALLOW_SAMPLES_CHANGE)
/* @} */
/* @} *//* Audio flags */

View File

@ -41,8 +41,10 @@
#include "SDL_config_android.h"
#elif defined(__PSP__)
#include "SDL_config_psp.h"
#elif defined(__OS2__)
#include "SDL_config_os2.h"
#else
/* This is a minimal configuration just to get SDL running on new platforms */
/* This is a minimal configuration just to get SDL running on new platforms. */
#include "SDL_config_minimal.h"
#endif /* platform config */

View File

@ -209,6 +209,11 @@
#cmakedefine HAVE_DINPUT_H @HAVE_DINPUT_H@
#cmakedefine HAVE_XINPUT_H @HAVE_XINPUT_H@
#cmakedefine HAVE_DXGI_H @HAVE_DXGI_H@
#cmakedefine HAVE_ENDPOINTVOLUME_H @HAVE_ENDPOINTVOLUME_H@
#cmakedefine HAVE_MMDEVICEAPI_H @HAVE_MMDEVICEAPI_H@
#cmakedefine HAVE_AUDIOCLIENT_H @HAVE_AUDIOCLIENT_H@
#cmakedefine HAVE_XINPUT_GAMEPAD_EX @HAVE_XINPUT_GAMEPAD_EX@
#cmakedefine HAVE_XINPUT_STATE_EX @HAVE_XINPUT_STATE_EX@

View File

@ -209,6 +209,9 @@
#undef HAVE_DSOUND_H
#undef HAVE_DXGI_H
#undef HAVE_XINPUT_H
#undef HAVE_ENDPOINTVOLUME_H
#undef HAVE_MMDEVICEAPI_H
#undef HAVE_AUDIOCLIENT_H
#undef HAVE_XINPUT_GAMEPAD_EX
#undef HAVE_XINPUT_STATE_EX

View File

@ -137,7 +137,7 @@
/* Enable MFi joystick support */
#define SDL_JOYSTICK_MFI 1
#define SDL_JOYSTICK_HIDAPI 1
/*#define SDL_JOYSTICK_HIDAPI 1*/
#ifdef __TVOS__
#define SDL_SENSOR_DUMMY 1

170
include/SDL_config_os2.h Normal file
View File

@ -0,0 +1,170 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_config_os2_h_
#define SDL_config_os2_h_
#define SDL_config_h_
#include "SDL_platform.h"
#define SDL_AUDIO_DRIVER_DUMMY 1
#define SDL_AUDIO_DRIVER_DISK 1
#define SDL_POWER_DISABLED 1
#define SDL_JOYSTICK_DISABLED 1
#define SDL_HAPTIC_DISABLED 1
/*#undef SDL_JOYSTICK_HIDAPI */
#define SDL_SENSOR_DUMMY 1
#define SDL_VIDEO_DRIVER_DUMMY 1
/* Enable OpenGL support */
/* #undef SDL_VIDEO_OPENGL */
/* Enable Vulkan support */
/* #undef SDL_VIDEO_VULKAN */
#define SDL_LOADSO_DISABLED 1
#define SDL_THREADS_DISABLED 1
#define SDL_TIMERS_DISABLED 1
#define SDL_FILESYSTEM_DUMMY 1
/* Enable assembly routines */
#define SDL_ASSEMBLY_ROUTINES 1
/* #undef HAVE_LIBSAMPLERATE_H */
/* Enable dynamic libsamplerate support */
/* #undef SDL_LIBSAMPLERATE_DYNAMIC */
#define HAVE_LIBC 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_STDIO_H 1
#define STDC_HEADERS 1
#define HAVE_STDLIB_H 1
#define HAVE_STDARG_H 1
#define HAVE_STDDEF_H 1
#define HAVE_MALLOC_H 1
#define HAVE_MEMORY_H 1
#define HAVE_STRING_H 1
#define HAVE_STRINGS_H 1
#define HAVE_WCHAR_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_STDINT_H 1
#define HAVE_LIMITS_H 1
#define HAVE_CTYPE_H 1
#define HAVE_MATH_H 1
#define HAVE_FLOAT_H 1
#define HAVE_SIGNAL_H 1
#define HAVE_MALLOC 1
#define HAVE_CALLOC 1
#define HAVE_REALLOC 1
#define HAVE_FREE 1
#if defined(__WATCOMC__)
#define HAVE__FSEEKI64 1
#define HAVE__FTELLI64 1
#endif
#define HAVE_ALLOCA 1
#define HAVE_GETENV 1
#define HAVE_SETENV 1
#define HAVE_PUTENV 1
#define HAVE_QSORT 1
#define HAVE_ABS 1
#define HAVE_BCOPY 1
#define HAVE_MEMSET 1
#define HAVE_MEMCPY 1
#define HAVE_MEMMOVE 1
#define HAVE_MEMCMP 1
#define HAVE_WCSLEN 1
#define HAVE_WCSLCPY 1
#define HAVE_WCSLCAT 1
#define HAVE_WCSCMP 1
#define HAVE_STRLEN 1
#define HAVE_STRLCPY 1
#define HAVE_STRLCAT 1
#define HAVE__STRREV 1
#define HAVE__STRUPR 1
#define HAVE__STRLWR 1
#define HAVE_INDEX 1
#define HAVE_RINDEX 1
#define HAVE_STRCHR 1
#define HAVE_STRRCHR 1
#define HAVE_STRSTR 1
#define HAVE_ITOA 1
#define HAVE__LTOA 1
#define HAVE__ULTOA 1
#define HAVE_STRTOL 1
#define HAVE_STRTOUL 1
#define HAVE__I64TOA 1
#define HAVE__UI64TOA 1
#define HAVE_STRTOLL 1
#define HAVE_STRTOULL 1
#define HAVE_STRTOD 1
#define HAVE_ATOI 1
#define HAVE_ATOF 1
#define HAVE_STRCMP 1
#define HAVE_STRNCMP 1
#define HAVE_STRICMP 1
#define HAVE_STRCASECMP 1
#define HAVE_STRNCASECMP 1
#define HAVE_SSCANF 1
#define HAVE_SNPRINTF 1
#define HAVE_VSNPRINTF 1
#define HAVE_SETJMP 1
#define HAVE_ACOS 1
/* #undef HAVE_ACOSF */
#define HAVE_ASIN 1
/* #undef HAVE_ASINF */
#define HAVE_ATAN 1
#define HAVE_ATAN2 1
/* #undef HAVE_ATAN2F */
#define HAVE_CEIL 1
/* #undef HAVE_CEILF */
/* #undef HAVE_COPYSIGN */
/* #undef HAVE_COPYSIGNF */
#define HAVE_COS 1
/* #undef HAVE_COSF */
#define HAVE_EXP 1
/* #undef HAVE_EXPF */
#define HAVE_FABS 1
/* #undef HAVE_FABSF */
#define HAVE_FLOOR 1
/* #undef HAVE_FLOORF */
#define HAVE_FMOD 1
/* #undef HAVE_FMODF */
#define HAVE_LOG 1
/* #undef HAVE_LOGF */
#define HAVE_LOG10 1
/* #undef HAVE_LOG10F */
#define HAVE_POW 1
/* #undef HAVE_POWF */
#define HAVE_SIN 1
/* #undef HAVE_SINF */
/* #undef HAVE_SCALBN */
/* #undef HAVE_SCALBNF */
#define HAVE_SQRT 1
/* #undef HAVE_SQRTF */
#define HAVE_TAN 1
/* #undef HAVE_TANF */
#endif /* SDL_config_os2_h_ */

View File

@ -82,6 +82,9 @@ typedef unsigned int uintptr_t;
#define HAVE_DSOUND_H 1
#define HAVE_DXGI_H 1
#define HAVE_XINPUT_H 1
#define HAVE_MMDEVICEAPI_H 1
#define HAVE_AUDIOCLIENT_H 1
#define HAVE_ENDPOINTVOLUME_H 1
/* This is disabled by default to avoid C runtime dependencies and manifest requirements */
#ifdef HAVE_LIBC

View File

@ -97,6 +97,11 @@ typedef unsigned int uintptr_t;
#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
#define HAVE_XINPUT_H 1
#endif
#define HAVE_MMDEVICEAPI_H 1
#define HAVE_AUDIOCLIENT_H 1
#define HAVE_ENDPOINTVOLUME_H 1
#define HAVE_LIBC 1
#define STDC_HEADERS 1
#define HAVE_CTYPE_H 1

View File

@ -204,6 +204,13 @@ extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromInstanceID(SDL
*/
extern DECLSPEC const char *SDLCALL SDL_GameControllerName(SDL_GameController *gamecontroller);
/**
* Get the player index of an opened game controller, or -1 if it's not available
*
* For XInput controllers this returns the XInput user index.
*/
extern DECLSPEC int SDLCALL SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller);
/**
* Get the USB vendor ID of an opened controller, if available.
* If the vendor ID isn't available this function returns 0.

View File

@ -117,6 +117,17 @@
extern "C" {
#endif /* __cplusplus */
/* FIXME: For SDL 2.1, adjust all the magnitude variables to be Uint16 (0xFFFF).
*
* At the moment the magnitude variables are mixed between signed/unsigned, and
* it is also not made clear that ALL of those variables expect a max of 0x7FFF.
*
* Some platforms may have higher precision than that (Linux FF, Windows XInput)
* so we should fix the inconsistency in favor of higher possible precision,
* adjusting for platforms that use different scales.
* -flibit
*/
/**
* \typedef SDL_Haptic
*

View File

@ -262,6 +262,16 @@ extern "C" {
*/
#define SDL_HINT_GRAB_KEYBOARD "SDL_GRAB_KEYBOARD"
/**
* \brief A variable setting the double click time, in milliseconds.
*/
#define SDL_HINT_MOUSE_DOUBLE_CLICK_TIME "SDL_MOUSE_DOUBLE_CLICK_TIME"
/**
* \brief A variable setting the double click radius, in pixels.
*/
#define SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS "SDL_MOUSE_DOUBLE_CLICK_RADIUS"
/**
* \brief A variable setting the speed scale for mouse motion, in floating point, when the mouse is not in relative mode
*/
@ -329,7 +339,7 @@ extern "C" {
#define SDL_HINT_IDLE_TIMER_DISABLED "SDL_IOS_IDLE_TIMER_DISABLED"
/**
* \brief A variable controlling which orientations are allowed on iOS.
* \brief A variable controlling which orientations are allowed on iOS/Android.
*
* In some circumstances it is necessary to be able to explicitly control
* which UI orientations are allowed.
@ -609,6 +619,10 @@ extern "C" {
* This is specially useful if you build SDL against a non glibc libc library (such as musl) which
* provides a relatively small default thread stack size (a few kilobytes versus the default 8MB glibc uses).
* Support for this hint is currently available only in the pthread, Windows, and PSP backend.
*
* Instead of this hint, in 2.0.9 and later, you can use
* SDL_CreateThreadWithStackSize(). This hint only works with the classic
* SDL_CreateThread().
*/
#define SDL_HINT_THREAD_STACK_SIZE "SDL_THREAD_STACK_SIZE"

View File

@ -132,6 +132,12 @@ extern DECLSPEC int SDLCALL SDL_NumJoysticks(void);
*/
extern DECLSPEC const char *SDLCALL SDL_JoystickNameForIndex(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.
*/
extern DECLSPEC int SDLCALL SDL_JoystickGetDevicePlayerIndex(int device_index);
/**
* Return the GUID for the joystick at this index
* This can be called before any joysticks are opened.
@ -194,6 +200,13 @@ extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromInstanceID(SDL_JoystickID
*/
extern DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick * joystick);
/**
* Get the player index of an opened joystick, or -1 if it's not available
*
* For XInput controllers this returns the XInput user index.
*/
extern DECLSPEC int SDLCALL SDL_JoystickGetPlayerIndex(SDL_Joystick * joystick);
/**
* Return the GUID for this opened joystick
*/

View File

@ -41,7 +41,7 @@ extern "C" {
#endif
/**
* \file SDL_sensor.h
* \brief SDL_sensor.h
*
* In order to use these functions, SDL_Init() must have been called
* with the ::SDL_INIT_SENSOR flag. This causes SDL to scan the system
@ -71,7 +71,7 @@ typedef enum
SDL_SENSOR_INVALID = -1, /**< Returned for an invalid sensor */
SDL_SENSOR_UNKNOWN, /**< Unknown sensor type */
SDL_SENSOR_ACCEL, /**< Accelerometer */
SDL_SENSOR_GYRO, /**< Gyroscope */
SDL_SENSOR_GYRO /**< Gyroscope */
} SDL_SensorType;
/**

View File

@ -248,6 +248,13 @@ extern DECLSPEC int SDLCALL SDL_SetSurfaceRLE(SDL_Surface * surface,
extern DECLSPEC int SDLCALL SDL_SetColorKey(SDL_Surface * surface,
int flag, Uint32 key);
/**
* \brief Returns whether the surface has a color key
*
* \return SDL_TRUE if the surface has a color key, or SDL_FALSE if the surface is NULL or has no color key
*/
extern DECLSPEC SDL_bool SDLCALL SDL_HasColorKey(SDL_Surface * surface);
/**
* \brief Gets the color key (transparent pixel) in a blittable surface.
*

View File

@ -106,14 +106,24 @@ SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread);
extern DECLSPEC SDL_Thread *SDLCALL
SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *),
const char *name, const size_t stacksize, void *data,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread);
/**
* Create a thread.
*/
#if defined(SDL_CreateThread) && SDL_DYNAMIC_API
#undef SDL_CreateThread
#define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
#undef SDL_CreateThreadWithStackSize
#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
#else
#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
#endif
#elif defined(__OS2__)
@ -133,15 +143,31 @@ extern DECLSPEC SDL_Thread *SDLCALL
SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread);
extern DECLSPEC SDL_Thread *SDLCALL
SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread);
#if defined(SDL_CreateThread) && SDL_DYNAMIC_API
#undef SDL_CreateThread
#define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
#undef SDL_CreateThreadWithStackSize
#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
#else
#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
#endif
#else
/**
* Create a thread with a default stack size.
*
* This is equivalent to calling:
* SDL_CreateThreadWithStackSize(fn, name, 0, data);
*/
extern DECLSPEC SDL_Thread *SDLCALL
SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
/**
* Create a thread.
*
@ -159,9 +185,17 @@ SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
* If a system imposes requirements, SDL will try to munge the string for
* it (truncate, etc), but the original string contents will be available
* from SDL_GetThreadName().
*
* The size (in bytes) of the new stack can be specified. Zero means "use
* the system default" which might be wildly different between platforms
* (x86 Linux generally defaults to eight megabytes, an embedded device
* might be a few kilobytes instead).
*
* In SDL 2.1, stacksize will be folded into the original SDL_CreateThread
* function.
*/
extern DECLSPEC SDL_Thread *SDLCALL
SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data);
#endif

View File

@ -59,7 +59,7 @@ typedef struct SDL_version
*/
#define SDL_MAJOR_VERSION 2
#define SDL_MINOR_VERSION 0
#define SDL_PATCHLEVEL 8
#define SDL_PATCHLEVEL 9
/**
* \brief Macro to determine SDL version program was compiled against.

View File

@ -175,7 +175,7 @@ typedef enum
typedef enum
{
SDL_DISPLAYEVENT_NONE, /**< Never used */
SDL_DISPLAYEVENT_ORIENTATION, /**< Display orientation has changed to data1 */
SDL_DISPLAYEVENT_ORIENTATION /**< Display orientation has changed to data1 */
} SDL_DisplayEventID;
typedef enum
@ -184,7 +184,7 @@ typedef enum
SDL_ORIENTATION_LANDSCAPE, /**< The display is in landscape mode, with the right side up, relative to portrait mode */
SDL_ORIENTATION_LANDSCAPE_FLIPPED, /**< The display is in landscape mode, with the left side up, relative to portrait mode */
SDL_ORIENTATION_PORTRAIT, /**< The display is in portrait mode */
SDL_ORIENTATION_PORTRAIT_FLIPPED, /**< The display is in portrait mode, upside down */
SDL_ORIENTATION_PORTRAIT_FLIPPED /**< The display is in portrait mode, upside down */
} SDL_DisplayOrientation;
/**

View File

@ -137,9 +137,9 @@ extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
*
* \param [in] \c NULL or window Window for which the required Vulkan instance
* extensions should be retrieved
* \param [in,out] count pointer to an \c unsigned related to the number of
* \param [in,out] pCount pointer to an \c unsigned related to the number of
* required Vulkan instance extensions
* \param [out] names \c NULL or a pointer to an array to be filled with the
* \param [out] pNames \c NULL or a pointer to an array to be filled with the
* required Vulkan instance extensions
*
* \return \c SDL_TRUE on success, \c SDL_FALSE on error.

View File

@ -124,11 +124,11 @@ SDL_InitSubSystem(Uint32 flags)
}
#if SDL_VIDEO_DRIVER_WINDOWS
if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) {
if (SDL_HelperWindowCreate() < 0) {
return -1;
}
}
if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) {
if (SDL_HelperWindowCreate() < 0) {
return -1;
}
}
#endif
#if !SDL_TIMERS_DISABLED
@ -263,8 +263,8 @@ SDL_QuitSubSystem(Uint32 flags)
#if !SDL_SENSOR_DISABLED
if ((flags & SDL_INIT_SENSOR)) {
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_SENSOR)) {
SDL_SensorQuit();
}
SDL_SensorQuit();
}
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_SENSOR);
}
#endif

View File

@ -19,6 +19,11 @@
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_assert_c_h_
#define SDL_assert_c_h_
extern void SDL_AssertionsQuit(void);
#endif /* SDL_assert_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -53,10 +53,11 @@
#endif
#if defined(__WATCOMC__) && defined(__386__)
SDL_COMPILE_TIME_ASSERT(intsize, 4==sizeof(int));
#define HAVE_WATCOM_ATOMICS
extern _inline int _SDL_xchg_watcom(volatile int *a, int v);
#pragma aux _SDL_xchg_watcom = \
"xchg [ecx], eax" \
"lock xchg [ecx], eax" \
parm [ecx] [eax] \
value [eax] \
modify exact [eax];

View File

@ -40,7 +40,7 @@
SDL_COMPILE_TIME_ASSERT(locksize, 4==sizeof(SDL_SpinLock));
extern _inline int _SDL_xchg_watcom(volatile int *a, int v);
#pragma aux _SDL_xchg_watcom = \
"xchg [ecx], eax" \
"lock xchg [ecx], eax" \
parm [ecx] [eax] \
value [eax] \
modify exact [eax];

View File

@ -378,21 +378,57 @@ static int
add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
{
int retval = -1;
const size_t size = sizeof (SDL_AudioDeviceItem) + SDL_strlen(name) + 1;
SDL_AudioDeviceItem *item = (SDL_AudioDeviceItem *) SDL_malloc(size);
if (item == NULL) {
return -1;
}
SDL_AudioDeviceItem *item;
const SDL_AudioDeviceItem *i;
int dupenum = 0;
SDL_assert(handle != NULL); /* we reserve NULL, audio backends can't use it. */
SDL_assert(name != NULL);
item = (SDL_AudioDeviceItem *) SDL_malloc(sizeof (SDL_AudioDeviceItem));
if (!item) {
return SDL_OutOfMemory();
}
item->original_name = SDL_strdup(name);
if (!item->original_name) {
SDL_free(item);
return SDL_OutOfMemory();
}
item->dupenum = 0;
item->name = item->original_name;
item->handle = handle;
SDL_strlcpy(item->name, name, size - sizeof (SDL_AudioDeviceItem));
SDL_LockMutex(current_audio.detectionLock);
for (i = *devices; i != NULL; i = i->next) {
if (SDL_strcmp(name, i->original_name) == 0) {
dupenum = i->dupenum + 1;
break; /* stop at the highest-numbered dupe. */
}
}
if (dupenum) {
const size_t len = SDL_strlen(name) + 16;
char *replacement = (char *) SDL_malloc(len);
if (!replacement) {
SDL_UnlockMutex(current_audio.detectionLock);
SDL_free(item->original_name);
SDL_free(item);
SDL_OutOfMemory();
return -1;
}
SDL_snprintf(replacement, len, "%s (%d)", name, dupenum + 1);
item->dupenum = dupenum;
item->name = replacement;
}
item->next = *devices;
*devices = item;
retval = (*devCount)++;
retval = (*devCount)++; /* !!! FIXME: this should be an atomic increment */
SDL_UnlockMutex(current_audio.detectionLock);
return retval;
@ -420,6 +456,11 @@ free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
if (item->handle != NULL) {
current_audio.impl.FreeDeviceHandle(item->handle);
}
/* these two pointers are the same if not a duplicate devname */
if (item->name != item->original_name) {
SDL_free(item->name);
}
SDL_free(item->original_name);
SDL_free(item);
}
*devices = NULL;
@ -977,6 +1018,11 @@ clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *re
} else {
*devices = next;
}
/* these two pointers are the same if not a duplicate devname */
if (item->name != item->original_name) {
SDL_free(item->name);
}
SDL_free(item->original_name);
SDL_free(item);
}
item = next;
@ -1003,7 +1049,6 @@ SDL_GetNumAudioDevices(int iscapture)
if (!iscapture && current_audio.outputDevicesRemoved) {
clean_out_device_list(&current_audio.outputDevices, &current_audio.outputDeviceCount, &current_audio.outputDevicesRemoved);
current_audio.outputDevicesRemoved = SDL_FALSE;
}
retval = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
@ -1130,8 +1175,9 @@ prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared)
}
case 1: /* Mono */
case 2: /* Stereo */
case 4: /* surround */
case 6: /* surround with center and lfe */
case 4: /* Quadrophonic */
case 6: /* 5.1 surround */
case 8: /* 7.1 surround */
break;
default:
SDL_SetError("Unsupported number of audio channels.");
@ -1324,15 +1370,12 @@ open_audio_device(const char *devname, int iscapture,
build_stream = SDL_TRUE;
}
}
/* !!! FIXME in 2.1: add SDL_AUDIO_ALLOW_SAMPLES_CHANGE flag?
As of 2.0.6, we will build a stream to buffer the difference between
what the app wants to feed and the device wants to eat, so everyone
gets their way. In prior releases, SDL would force the callback to
feed at the rate the device requested, adjusted for resampling.
*/
if (device->spec.samples != obtained->samples) {
build_stream = SDL_TRUE;
if (allowed_changes & SDL_AUDIO_ALLOW_SAMPLES_CHANGE) {
obtained->samples = device->spec.samples;
} else {
build_stream = SDL_TRUE;
}
}
SDL_CalculateAudioSpec(obtained); /* recalc after possible changes. */

View File

@ -18,6 +18,10 @@
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_audiodev_c_h_
#define SDL_audiodev_c_h_
#include "SDL.h"
#include "../SDL_internal.h"
#include "SDL_sysaudio.h"
@ -35,4 +39,6 @@
extern void SDL_EnumUnixAudioDevices(const int classic, int (*test)(int));
#endif /* SDL_audiodev_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -25,7 +25,8 @@
#include "SDL_cpuinfo.h"
#include "SDL_assert.h"
#ifdef __ARM_NEON__
/* !!! FIXME: disabled until we fix https://bugzilla.libsdl.org/show_bug.cgi?id=4186 */
#if 0 /*def __ARM_NEON__*/
#define HAVE_NEON_INTRINSICS 1
#endif

View File

@ -98,8 +98,10 @@ typedef struct SDL_AudioDriverImpl
typedef struct SDL_AudioDeviceItem
{
void *handle;
char *name;
char *original_name;
int dupenum;
struct SDL_AudioDeviceItem *next;
char name[SDL_VARIABLE_LENGTH_ARRAY];
} SDL_AudioDeviceItem;

View File

@ -445,7 +445,7 @@ static void
ALSA_CloseDevice(_THIS)
{
if (this->hidden->pcm_handle) {
/* Wait for the submitted audio to drain
/* Wait for the submitted audio to drain
ALSA_snd_pcm_drop() can hang, so don't use that.
*/
Uint32 delay = ((this->spec.samples * 1000) / this->spec.freq) * 2;

View File

@ -57,7 +57,9 @@ ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
test_format = SDL_FirstAudioFormat(this->spec.format);
while (test_format != 0) { /* no "UNKNOWN" constant */
if ((test_format == AUDIO_U8) || (test_format == AUDIO_S16LSB)) {
if ((test_format == AUDIO_U8) ||
(test_format == AUDIO_S16) ||
(test_format == AUDIO_F32)) {
this->spec.format = test_format;
break;
}
@ -69,25 +71,8 @@ ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
return SDL_SetError("No compatible audio format!");
}
if (this->spec.channels > 1) {
this->spec.channels = 2;
} else {
this->spec.channels = 1;
}
if (this->spec.freq < 8000) {
this->spec.freq = 8000;
}
if (this->spec.freq > 48000) {
this->spec.freq = 48000;
}
/* TODO: pass in/return a (Java) device ID */
this->spec.samples = Android_JNI_OpenAudioDevice(iscapture, this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples);
if (this->spec.samples == 0) {
/* Init failed? */
return SDL_SetError("Java-side initialization failed!");
if (Android_JNI_OpenAudioDevice(iscapture, &this->spec) < 0) {
return -1;
}
SDL_CalculateAudioSpec(&this->spec);

View File

@ -39,7 +39,7 @@
#include "SDL_name.h"
#include "SDL_loadso.h"
#else
#define SDL_NAME(X) X
#define SDL_NAME(X) X
#endif
#ifdef SDL_AUDIO_DRIVER_ARTS_DYNAMIC

View File

@ -477,8 +477,8 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
SDL_bool tried_format = SDL_FALSE;
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
LPGUID guid = (LPGUID) handle;
DWORD bufsize;
DWORD bufsize;
/* Initialize all variables that we clean on shutdown */
this->hidden = (struct SDL_PrivateAudioData *)
SDL_malloc((sizeof *this->hidden));
@ -526,7 +526,7 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
(int) (DSBSIZE_MAX / numchunks));
} else {
int rc;
WAVEFORMATEX wfmt;
WAVEFORMATEX wfmt;
SDL_zero(wfmt);
if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
wfmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;

View File

@ -109,7 +109,7 @@ static pa_operation * (*PULSEAUDIO_pa_stream_drain) (pa_stream *,
pa_stream_success_cb_t, void *);
static int (*PULSEAUDIO_pa_stream_peek) (pa_stream *, const void **, size_t *);
static int (*PULSEAUDIO_pa_stream_drop) (pa_stream *);
static pa_operation * (*PULSEAUDIO_pa_stream_flush) (pa_stream *,
static pa_operation * (*PULSEAUDIO_pa_stream_flush) (pa_stream *,
pa_stream_success_cb_t, void *);
static int (*PULSEAUDIO_pa_stream_disconnect) (pa_stream *);
static void (*PULSEAUDIO_pa_stream_unref) (pa_stream *);

View File

@ -725,6 +725,12 @@ WASAPI_ThreadDeinit(_THIS)
WASAPI_PlatformThreadDeinit(this);
}
void
WASAPI_BeginLoopIteration(_THIS)
{
/* no-op. */
}
static void
WASAPI_Deinitialize(void)
{

View File

@ -351,10 +351,42 @@ WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
}
typedef struct
{
LPWSTR devid;
char *devname;
} EndpointItem;
static int sort_endpoints(const void *_a, const void *_b)
{
LPWSTR a = ((const EndpointItem *) _a)->devid;
LPWSTR b = ((const EndpointItem *) _b)->devid;
if (!a && b) {
return -1;
} else if (a && !b) {
return 1;
}
while (SDL_TRUE) {
if (*a < *b) {
return -1;
} else if (*a > *b) {
return 1;
} else if (*a == 0) {
break;
}
a++;
b++;
}
return 0;
}
static void
WASAPI_EnumerateEndpointsForFlow(const SDL_bool iscapture)
{
IMMDeviceCollection *collection = NULL;
EndpointItem *items;
UINT i, total;
/* Note that WASAPI separates "adapter devices" from "audio endpoint devices"
@ -369,22 +401,36 @@ WASAPI_EnumerateEndpointsForFlow(const SDL_bool iscapture)
return;
}
items = (EndpointItem *) SDL_calloc(total, sizeof (EndpointItem));
if (!items) {
return; /* oh well. */
}
for (i = 0; i < total; i++) {
EndpointItem *item = items + i;
IMMDevice *device = NULL;
if (SUCCEEDED(IMMDeviceCollection_Item(collection, i, &device))) {
LPWSTR devid = NULL;
if (SUCCEEDED(IMMDevice_GetId(device, &devid))) {
char *devname = GetWasapiDeviceName(device);
if (devname) {
WASAPI_AddDevice(iscapture, devname, devid);
SDL_free(devname);
}
CoTaskMemFree(devid);
if (SUCCEEDED(IMMDevice_GetId(device, &item->devid))) {
item->devname = GetWasapiDeviceName(device);
}
IMMDevice_Release(device);
}
}
/* sort the list of devices by their guid so list is consistent between runs */
SDL_qsort(items, total, sizeof (*items), sort_endpoints);
/* Send the sorted list on to the SDL's higher level. */
for (i = 0; i < total; i++) {
EndpointItem *item = items + i;
if ((item->devid) && (item->devname)) {
WASAPI_AddDevice(iscapture, item->devname, item->devid);
}
SDL_free(item->devname);
CoTaskMemFree(item->devid);
}
SDL_free(items);
IMMDeviceCollection_Release(collection);
}
@ -405,12 +451,6 @@ WASAPI_PlatformDeleteActivationHandler(void *handler)
SDL_assert(!"This function should have only been called on WinRT.");
}
void
WASAPI_BeginLoopIteration(_THIS)
{
/* no-op. */
}
#endif /* SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__) */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -185,20 +185,9 @@ struct SDL_WasapiActivationHandler : public RuntimeClass< RuntimeClassFlags< Cla
HRESULT
SDL_WasapiActivationHandler::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *async)
{
HRESULT result = S_OK;
IUnknown *iunknown = nullptr;
const HRESULT ret = async->GetActivateResult(&result, &iunknown);
if (SUCCEEDED(ret) && SUCCEEDED(result)) {
iunknown->QueryInterface(IID_PPV_ARGS(&device->hidden->client));
if (device->hidden->client) {
// Just set a flag, since we're probably in a different thread. We'll pick it up and init everything on our own thread to prevent races.
SDL_AtomicSet(&device->hidden->just_activated, 1);
}
}
// Just set a flag, since we're probably in a different thread. We'll pick it up and init everything on our own thread to prevent races.
SDL_AtomicSet(&device->hidden->just_activated, 1);
WASAPI_UnrefDevice(device);
return S_OK;
}
@ -236,27 +225,47 @@ WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
IActivateAudioInterfaceAsyncOperation *async = nullptr;
const HRESULT ret = ActivateAudioInterfaceAsync(devid, __uuidof(IAudioClient), nullptr, handler.Get(), &async);
if (async != nullptr) {
async->Release();
}
if (FAILED(ret)) {
if (FAILED(ret) || async == nullptr) {
if (async != nullptr) {
async->Release();
}
handler.Get()->Release();
WASAPI_UnrefDevice(_this);
return WIN_SetErrorFromHRESULT("WASAPI can't activate requested audio endpoint", ret);
}
return 0;
}
void
WASAPI_BeginLoopIteration(_THIS)
{
if (SDL_AtomicCAS(&_this->hidden->just_activated, 1, 0)) {
if (WASAPI_PrepDevice(_this, SDL_TRUE) == -1) {
SDL_OpenedAudioDeviceDisconnected(_this);
}
/* Spin until the async operation is complete.
* If we don't PrepDevice before leaving this function, the bug list gets LONG:
* - device.spec is not filled with the correct information
* - The 'obtained' spec will be wrong for ALLOW_CHANGE properties
* - SDL_AudioStreams will/will not be allocated at the right time
* - SDL_assert(device->callbackspec.size == device->spec.size) will fail
* - When the assert is ignored, skipping or a buffer overflow will occur
*/
while (!SDL_AtomicCAS(&_this->hidden->just_activated, 1, 0)) {
SDL_Delay(1);
}
HRESULT activateRes = S_OK;
IUnknown *iunknown = nullptr;
const HRESULT getActivateRes = async->GetActivateResult(&activateRes, &iunknown);
async->Release();
if (FAILED(getActivateRes)) {
return WIN_SetErrorFromHRESULT("Failed to get WASAPI activate result", getActivateRes);
} else if (FAILED(activateRes)) {
return WIN_SetErrorFromHRESULT("Failed to activate WASAPI device", activateRes);
}
iunknown->QueryInterface(IID_PPV_ARGS(&_this->hidden->client));
if (!_this->hidden->client) {
return SDL_SetError("Failed to query WASAPI client interface");
}
if (WASAPI_PrepDevice(_this, isrecovery) == -1) {
return -1;
}
return 0;
}
void

View File

@ -78,7 +78,7 @@ static void DetectWave##typ##Devs(void) { \
capstyp##2W caps; \
UINT i; \
for (i = 0; i < devcount; i++) { \
if (wave##typ##GetDevCaps(i,(LP##capstyp##W)&caps,sizeof(caps))==MMSYSERR_NOERROR) { \
if (wave##typ##GetDevCaps(i,(LP##capstyp##W)&caps,sizeof(caps))==MMSYSERR_NOERROR) { \
char *name = WIN_LookupAudioDeviceName(caps.szPname,&caps.NameGuid); \
if (name != NULL) { \
SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \
@ -375,8 +375,7 @@ WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
#endif
/* Create the audio buffer semaphore */
this->hidden->audio_sem =
CreateSemaphore(NULL, iscapture ? 0 : NUM_BUFFERS - 1, NUM_BUFFERS, NULL);
this->hidden->audio_sem = CreateSemaphore(NULL, iscapture ? 0 : NUM_BUFFERS - 1, NUM_BUFFERS, NULL);
if (this->hidden->audio_sem == NULL) {
return SDL_SetError("Couldn't create semaphore");
}

View File

@ -61,6 +61,10 @@
#define SDL_JAVA_CONTROLLER_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLControllerManager, function)
#define SDL_JAVA_INTERFACE_INPUT_CONNECTION(function) CONCAT1(SDL_JAVA_PREFIX, SDLInputConnection, function)
/* Audio encoding definitions */
#define ENCODING_PCM_8BIT 3
#define ENCODING_PCM_16BIT 2
#define ENCODING_PCM_FLOAT 4
/* Java class SDLActivity */
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(
@ -77,7 +81,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)(
JNIEnv* env, jclass jcls,
jint surfaceWidth, jint surfaceHeight,
jint deviceWidth, jint deviceHeight, jint format, jfloat rate);
jint deviceWidth, jint deviceHeight, jint format, jfloat rate);
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(
JNIEnv* env, jclass jcls);
@ -144,6 +148,10 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)(
JNIEnv* env, jclass cls,
jstring text, jint newCursorPosition);
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)(
JNIEnv* env, jclass cls,
jchar chUnicode);
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)(
JNIEnv* env, jclass cls,
jstring text, jint newCursorPosition);
@ -195,6 +203,7 @@ JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)(
/* #define DEBUG_JNI */
static void Android_JNI_ThreadDestroyed(void*);
static void checkJNIReady(void);
/*******************************************************************************
This file links the Java side of Android with libsdl
@ -243,12 +252,14 @@ static jclass mAudioManagerClass;
/* method signatures */
static jmethodID midAudioOpen;
static jmethodID midAudioWriteShortBuffer;
static jmethodID midAudioWriteByteBuffer;
static jmethodID midAudioWriteShortBuffer;
static jmethodID midAudioWriteFloatBuffer;
static jmethodID midAudioClose;
static jmethodID midCaptureOpen;
static jmethodID midCaptureReadShortBuffer;
static jmethodID midCaptureReadByteBuffer;
static jmethodID midCaptureReadShortBuffer;
static jmethodID midCaptureReadFloatBuffer;
static jmethodID midCaptureClose;
/* controller manager */
@ -392,24 +403,28 @@ JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jc
mAudioManagerClass = (jclass)((*mEnv)->NewGlobalRef(mEnv, cls));
midAudioOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"audioOpen", "(IZZI)I");
midAudioWriteShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"audioWriteShortBuffer", "([S)V");
"audioOpen", "(IIII)[I");
midAudioWriteByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"audioWriteByteBuffer", "([B)V");
midAudioWriteShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"audioWriteShortBuffer", "([S)V");
midAudioWriteFloatBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"audioWriteFloatBuffer", "([F)V");
midAudioClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"audioClose", "()V");
midCaptureOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"captureOpen", "(IZZI)I");
midCaptureReadShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"captureReadShortBuffer", "([SZ)I");
"captureOpen", "(IIII)[I");
midCaptureReadByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"captureReadByteBuffer", "([BZ)I");
midCaptureReadShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"captureReadShortBuffer", "([SZ)I");
midCaptureReadFloatBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"captureReadFloatBuffer", "([FZ)I");
midCaptureClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"captureClose", "()V");
if (!midAudioOpen || !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioClose ||
!midCaptureOpen || !midCaptureReadShortBuffer || !midCaptureReadByteBuffer || !midCaptureClose) {
if (!midAudioOpen || !midAudioWriteByteBuffer || !midAudioWriteShortBuffer || !midAudioWriteFloatBuffer || !midAudioClose ||
!midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || !midCaptureReadFloatBuffer || !midCaptureClose) {
__android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?");
}
@ -430,7 +445,7 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv* mEn
midPollHapticDevices = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass,
"pollHapticDevices", "()V");
midHapticRun = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass,
"hapticRun", "(II)V");
"hapticRun", "(IFI)V");
midHapticStop = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass,
"hapticStop", "(I)V");
@ -538,7 +553,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)(
JNIEnv* env, jclass jcls,
jint surfaceWidth, jint surfaceHeight,
jint deviceWidth, jint deviceHeight, jint format, jfloat rate)
jint deviceWidth, jint deviceHeight, jint format, jfloat rate)
{
Android_SetScreenResolution(surfaceWidth, surfaceHeight, deviceWidth, deviceHeight, format, rate);
}
@ -1039,17 +1054,19 @@ int Android_JNI_SetupThread(void)
/*
* Audio support
*/
static jboolean audioBuffer16Bit = JNI_FALSE;
static int audioBufferFormat = 0;
static jobject audioBuffer = NULL;
static void* audioBufferPinned = NULL;
static jboolean captureBuffer16Bit = JNI_FALSE;
static int captureBufferFormat = 0;
static jobject captureBuffer = NULL;
int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames)
int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec)
{
jboolean audioBufferStereo;
int audioBufferFrames;
int audioformat;
int numBufferFrames;
jobject jbufobj = NULL;
jobject result;
int *resultElements;
jboolean isCopy;
JNIEnv *env = Android_JNI_GetEnv();
@ -1059,74 +1076,123 @@ int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int
}
Android_JNI_SetupThread();
audioBufferStereo = channelCount > 1;
switch (spec->format) {
case AUDIO_U8:
audioformat = ENCODING_PCM_8BIT;
break;
case AUDIO_S16:
audioformat = ENCODING_PCM_16BIT;
break;
case AUDIO_F32:
audioformat = ENCODING_PCM_FLOAT;
break;
default:
return SDL_SetError("Unsupported audio format: 0x%x", spec->format);
}
if (iscapture) {
__android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for capture");
captureBuffer16Bit = is16Bit;
if ((*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) {
/* Error during audio initialization */
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioRecord initialization!");
return 0;
}
result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midCaptureOpen, spec->freq, audioformat, spec->channels, spec->samples);
} else {
__android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for output");
audioBuffer16Bit = is16Bit;
if ((*env)->CallStaticIntMethod(env, mAudioManagerClass, midAudioOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) {
/* Error during audio initialization */
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioTrack initialization!");
return 0;
}
result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midAudioOpen, spec->freq, audioformat, spec->channels, spec->samples);
}
if (result == NULL) {
/* Error during audio initialization, error printed from Java */
return SDL_SetError("Java-side initialization failed");
}
if ((*env)->GetArrayLength(env, (jintArray)result) != 4) {
return SDL_SetError("Unexpected results from Java, expected 4, got %d", (*env)->GetArrayLength(env, (jintArray)result));
}
isCopy = JNI_FALSE;
resultElements = (*env)->GetIntArrayElements(env, (jintArray)result, &isCopy);
spec->freq = resultElements[0];
audioformat = resultElements[1];
switch (audioformat) {
case ENCODING_PCM_8BIT:
spec->format = AUDIO_U8;
break;
case ENCODING_PCM_16BIT:
spec->format = AUDIO_S16;
break;
case ENCODING_PCM_FLOAT:
spec->format = AUDIO_F32;
break;
default:
return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat);
}
spec->channels = resultElements[2];
spec->samples = resultElements[3];
(*env)->ReleaseIntArrayElements(env, (jintArray)result, resultElements, JNI_ABORT);
(*env)->DeleteLocalRef(env, result);
/* Allocating the audio buffer from the Java side and passing it as the return value for audioInit no longer works on
* Android >= 4.2 due to a "stale global reference" error. So now we allocate this buffer directly from this side. */
if (is16Bit) {
jshortArray audioBufferLocal = (*env)->NewShortArray(env, desiredBufferFrames * (audioBufferStereo ? 2 : 1));
if (audioBufferLocal) {
jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
(*env)->DeleteLocalRef(env, audioBufferLocal);
switch (audioformat) {
case ENCODING_PCM_8BIT:
{
jbyteArray audioBufferLocal = (*env)->NewByteArray(env, spec->samples * spec->channels);
if (audioBufferLocal) {
jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
(*env)->DeleteLocalRef(env, audioBufferLocal);
}
}
}
else {
jbyteArray audioBufferLocal = (*env)->NewByteArray(env, desiredBufferFrames * (audioBufferStereo ? 2 : 1));
if (audioBufferLocal) {
jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
(*env)->DeleteLocalRef(env, audioBufferLocal);
break;
case ENCODING_PCM_16BIT:
{
jshortArray audioBufferLocal = (*env)->NewShortArray(env, spec->samples * spec->channels);
if (audioBufferLocal) {
jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
(*env)->DeleteLocalRef(env, audioBufferLocal);
}
}
break;
case ENCODING_PCM_FLOAT:
{
jfloatArray audioBufferLocal = (*env)->NewFloatArray(env, spec->samples * spec->channels);
if (audioBufferLocal) {
jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
(*env)->DeleteLocalRef(env, audioBufferLocal);
}
}
break;
default:
return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat);
}
if (jbufobj == NULL) {
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer!");
return 0;
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer");
return SDL_OutOfMemory();
}
if (iscapture) {
captureBufferFormat = audioformat;
captureBuffer = jbufobj;
} else {
audioBufferFormat = audioformat;
audioBuffer = jbufobj;
}
numBufferFrames = (*env)->GetArrayLength(env, (jarray)jbufobj);
isCopy = JNI_FALSE;
if (!iscapture) {
isCopy = JNI_FALSE;
if (is16Bit) {
if (!iscapture) {
audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy);
}
audioBufferFrames = (*env)->GetArrayLength(env, (jshortArray)audioBuffer);
} else {
if (!iscapture) {
switch (audioformat) {
case ENCODING_PCM_8BIT:
audioBufferPinned = (*env)->GetByteArrayElements(env, (jbyteArray)audioBuffer, &isCopy);
break;
case ENCODING_PCM_16BIT:
audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy);
break;
case ENCODING_PCM_FLOAT:
audioBufferPinned = (*env)->GetFloatArrayElements(env, (jfloatArray)audioBuffer, &isCopy);
break;
default:
return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat);
}
audioBufferFrames = (*env)->GetArrayLength(env, (jbyteArray)audioBuffer);
}
if (audioBufferStereo) {
audioBufferFrames /= 2;
}
return audioBufferFrames;
return 0;
}
int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi)
@ -1170,12 +1236,22 @@ void Android_JNI_WriteAudioBuffer(void)
{
JNIEnv *mAudioEnv = Android_JNI_GetEnv();
if (audioBuffer16Bit) {
(*mAudioEnv)->ReleaseShortArrayElements(mAudioEnv, (jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT);
(*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
} else {
switch (audioBufferFormat) {
case ENCODING_PCM_8BIT:
(*mAudioEnv)->ReleaseByteArrayElements(mAudioEnv, (jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT);
(*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer);
break;
case ENCODING_PCM_16BIT:
(*mAudioEnv)->ReleaseShortArrayElements(mAudioEnv, (jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT);
(*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
break;
case ENCODING_PCM_FLOAT:
(*mAudioEnv)->ReleaseFloatArrayElements(mAudioEnv, (jfloatArray)audioBuffer, (jfloat *)audioBufferPinned, JNI_COMMIT);
(*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteFloatBuffer, (jfloatArray)audioBuffer);
break;
default:
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: unhandled audio buffer format");
break;
}
/* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */
@ -1187,16 +1263,8 @@ int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen)
jboolean isCopy = JNI_FALSE;
jint br;
if (captureBuffer16Bit) {
SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen / 2));
br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_TRUE);
if (br > 0) {
jshort *ptr = (*env)->GetShortArrayElements(env, (jshortArray)captureBuffer, &isCopy);
br *= 2;
SDL_memcpy(buffer, ptr, br);
(*env)->ReleaseShortArrayElements(env, (jshortArray)captureBuffer, (jshort *)ptr, JNI_ABORT);
}
} else {
switch (captureBufferFormat) {
case ENCODING_PCM_8BIT:
SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == buflen);
br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_TRUE);
if (br > 0) {
@ -1204,27 +1272,75 @@ int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen)
SDL_memcpy(buffer, ptr, br);
(*env)->ReleaseByteArrayElements(env, (jbyteArray)captureBuffer, (jbyte *)ptr, JNI_ABORT);
}
break;
case ENCODING_PCM_16BIT:
SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen / sizeof(Sint16)));
br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_TRUE);
if (br > 0) {
jshort *ptr = (*env)->GetShortArrayElements(env, (jshortArray)captureBuffer, &isCopy);
br *= sizeof(Sint16);
SDL_memcpy(buffer, ptr, br);
(*env)->ReleaseShortArrayElements(env, (jshortArray)captureBuffer, (jshort *)ptr, JNI_ABORT);
}
break;
case ENCODING_PCM_FLOAT:
SDL_assert((*env)->GetArrayLength(env, (jfloatArray)captureBuffer) == (buflen / sizeof(float)));
br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_TRUE);
if (br > 0) {
jfloat *ptr = (*env)->GetFloatArrayElements(env, (jfloatArray)captureBuffer, &isCopy);
br *= sizeof(float);
SDL_memcpy(buffer, ptr, br);
(*env)->ReleaseFloatArrayElements(env, (jfloatArray)captureBuffer, (jfloat *)ptr, JNI_ABORT);
}
break;
default:
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: unhandled capture buffer format");
break;
}
return (int) br;
return br;
}
void Android_JNI_FlushCapturedAudio(void)
{
JNIEnv *env = Android_JNI_GetEnv();
#if 0 /* !!! FIXME: this needs API 23, or it'll do blocking reads and never end. */
if (captureBuffer16Bit) {
const jint len = (*env)->GetArrayLength(env, (jshortArray)captureBuffer);
while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }
} else {
const jint len = (*env)->GetArrayLength(env, (jbyteArray)captureBuffer);
while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }
switch (captureBufferFormat) {
case ENCODING_PCM_8BIT:
{
const jint len = (*env)->GetArrayLength(env, (jbyteArray)captureBuffer);
while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }
}
break;
case ENCODING_PCM_16BIT:
{
const jint len = (*env)->GetArrayLength(env, (jshortArray)captureBuffer);
while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }
}
break;
case ENCODING_PCM_FLOAT:
{
const jint len = (*env)->GetArrayLength(env, (jfloatArray)captureBuffer);
while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }
}
break;
default:
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: flushing unhandled capture buffer format");
break;
}
#else
if (captureBuffer16Bit) {
(*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE);
} else {
switch (captureBufferFormat) {
case ENCODING_PCM_8BIT:
(*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE);
break;
case ENCODING_PCM_16BIT:
(*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE);
break;
case ENCODING_PCM_FLOAT:
(*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE);
break;
default:
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: flushing unhandled capture buffer format");
break;
}
#endif
}
@ -1890,10 +2006,10 @@ void Android_JNI_PollHapticDevices(void)
(*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollHapticDevices);
}
void Android_JNI_HapticRun(int device_id, int length)
void Android_JNI_HapticRun(int device_id, float intensity, int length)
{
JNIEnv *env = Android_JNI_GetEnv();
(*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticRun, device_id, length);
(*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticRun, device_id, intensity, length);
}
void Android_JNI_HapticStop(int device_id)

View File

@ -19,6 +19,7 @@
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#include "SDL_system.h"
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
@ -30,6 +31,7 @@ extern "C" {
#include <EGL/eglplatform.h>
#include <android/native_window_jni.h>
#include "SDL_audio.h"
#include "SDL_rect.h"
/* Interface from the SDL library into the Android Java activity */
@ -46,13 +48,17 @@ extern ANativeWindow* Android_JNI_GetNativeWindow(void);
extern int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi);
/* Audio support */
extern int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames);
extern int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec);
extern void* Android_JNI_GetAudioBuffer(void);
extern void Android_JNI_WriteAudioBuffer(void);
extern int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen);
extern void Android_JNI_FlushCapturedAudio(void);
extern void Android_JNI_CloseAudioDevice(const int iscapture);
/* Detecting device type */
extern SDL_bool Android_IsDeXMode();
extern SDL_bool Android_IsChromebook();
#include "SDL_rwops.h"
int Android_JNI_FileOpen(SDL_RWops* ctx, const char* fileName, const char* mode);
@ -78,15 +84,16 @@ void Android_JNI_PollInputDevices(void);
/* Haptic support */
void Android_JNI_PollHapticDevices(void);
void Android_JNI_HapticRun(int device_id, int length);
void Android_JNI_HapticRun(int device_id, float intensity, int length);
void Android_JNI_HapticStop(int device_id);
/* Video */
void Android_JNI_SuspendScreenSaver(SDL_bool suspend);
/* Touch support */
int Android_JNI_GetTouchDeviceIds(int **ids);
int Android_JNI_InitTouch(void);
void Android_JNI_SetSeparateMouseAndTouch(SDL_bool new_value);
int Android_JNI_GetTouchDeviceIds(int **ids);
/* Threads */
#include <jni.h>
@ -109,9 +116,15 @@ SDL_bool Android_JNI_SetCustomCursor(int cursorID);
SDL_bool Android_JNI_SetSystemCursor(int cursorID);
/* Relative mouse support */
SDL_bool Android_JNI_SupportsRelativeMouse();
SDL_bool Android_JNI_SupportsRelativeMouse(void);
SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled);
SDL_bool SDL_IsAndroidTablet(void);
SDL_bool SDL_IsAndroidTV(void);
SDL_bool SDL_IsChromebook(void);
SDL_bool SDL_IsDeXMode(void);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
/* *INDENT-OFF* */

View File

@ -39,9 +39,8 @@ typedef struct SDL_DBusContext {
void (*bus_add_match)(DBusConnection *, const char *, DBusError *);
DBusConnection * (*connection_open_private)(const char *, DBusError *);
void (*connection_set_exit_on_disconnect)(DBusConnection *, dbus_bool_t);
dbus_bool_t (*connection_get_is_connected)(DBusConnection *);
dbus_bool_t (*connection_add_filter)(DBusConnection *, DBusHandleMessageFunction,
void *, DBusFreeFunction);
dbus_bool_t (*connection_get_is_connected)(DBusConnection *);
dbus_bool_t (*connection_add_filter)(DBusConnection *, DBusHandleMessageFunction, void *, DBusFreeFunction);
dbus_bool_t (*connection_try_register_object_path)(DBusConnection *, const char *,
const DBusObjectPathVTable *, void *, DBusError *);
dbus_bool_t (*connection_send)(DBusConnection *, DBusMessage *, dbus_uint32_t *);
@ -51,7 +50,7 @@ typedef struct SDL_DBusContext {
void (*connection_flush)(DBusConnection *);
dbus_bool_t (*connection_read_write)(DBusConnection *, int);
DBusDispatchStatus (*connection_dispatch)(DBusConnection *);
dbus_bool_t (*message_is_signal)(DBusMessage *, const char *, const char *);
dbus_bool_t (*message_is_signal)(DBusMessage *, const char *, const char *);
DBusMessage *(*message_new_method_call)(const char *, const char *, const char *, const char *);
dbus_bool_t (*message_append_args)(DBusMessage *, int, ...);
dbus_bool_t (*message_append_args_valist)(DBusMessage *, int, va_list);
@ -61,7 +60,7 @@ typedef struct SDL_DBusContext {
dbus_bool_t (*message_iter_next)(DBusMessageIter *);
void (*message_iter_get_basic)(DBusMessageIter *, void *);
int (*message_iter_get_arg_type)(DBusMessageIter *);
void (*message_iter_recurse)(DBusMessageIter *, DBusMessageIter *);
void (*message_iter_recurse)(DBusMessageIter *, DBusMessageIter *);
void (*message_unref)(DBusMessage *);
void (*error_init)(DBusError *);
dbus_bool_t (*error_is_set)(const DBusError *);

View File

@ -198,7 +198,7 @@ static SDL_EVDEV_keyboard_state * kbd_cleanup_state = NULL;
static int kbd_cleanup_sigactions_installed = 0;
static int kbd_cleanup_atexit_installed = 0;
static struct sigaction old_sigaction[NSIG] = { 0 };
static struct sigaction old_sigaction[NSIG];
static int fatal_signals[] =
{
@ -510,17 +510,19 @@ static unsigned int handle_diacr(SDL_EVDEV_keyboard_state *kbd, unsigned int ch)
static int vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag)
{
return ((kbd->ledflagstate >> flag) & 1);
return (kbd->ledflagstate & flag) != 0;
}
static void set_vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag)
{
kbd->ledflagstate |= 1 << flag;
kbd->ledflagstate |= flag;
ioctl(kbd->console_fd, KDSETLED, (unsigned long)(kbd->ledflagstate));
}
static void clr_vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag)
{
kbd->ledflagstate &= ~(1 << flag);
kbd->ledflagstate &= ~flag;
ioctl(kbd->console_fd, KDSETLED, (unsigned long)(kbd->ledflagstate));
}
static void chg_vc_kbd_lock(SDL_EVDEV_keyboard_state *kbd, int flag)
@ -535,7 +537,8 @@ static void chg_vc_kbd_slock(SDL_EVDEV_keyboard_state *kbd, int flag)
static void chg_vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag)
{
kbd->ledflagstate ^= 1 << flag;
kbd->ledflagstate ^= flag;
ioctl(kbd->console_fd, KDSETLED, (unsigned long)(kbd->ledflagstate));
}
/*

View File

@ -19,6 +19,9 @@
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_evdev_kbd_h_
#define SDL_evdev_kbd_h_
struct SDL_EVDEV_keyboard_state;
typedef struct SDL_EVDEV_keyboard_state SDL_EVDEV_keyboard_state;
@ -26,4 +29,6 @@ extern SDL_EVDEV_keyboard_state *SDL_EVDEV_kbd_init(void);
extern void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *state, unsigned int keycode, int down);
extern void SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *state);
#endif /* SDL_evdev_kbd_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -63,7 +63,7 @@ SDL_UDEV_load_syms(void)
{
/* cast funcs to char* first, to please GCC's strict aliasing rules. */
#define SDL_UDEV_SYM(x) \
if (!SDL_UDEV_load_sym(#x, (void **) (char *) & _this->x)) return -1
if (!SDL_UDEV_load_sym(#x, (void **) (char *) & _this->syms.x)) return -1
SDL_UDEV_SYM(udev_device_get_action);
SDL_UDEV_SYM(udev_device_get_devnode);
@ -100,7 +100,7 @@ static SDL_bool
SDL_UDEV_hotplug_update_available(void)
{
if (_this->udev_mon != NULL) {
const int fd = _this->udev_monitor_get_fd(_this->udev_mon);
const int fd = _this->syms.udev_monitor_get_fd(_this->udev_mon);
if (SDL_IOReady(fd, SDL_FALSE, 0)) {
return SDL_TRUE;
}
@ -130,21 +130,21 @@ SDL_UDEV_Init(void)
* Listen for input devices (mouse, keyboard, joystick, etc) and sound devices
*/
_this->udev = _this->udev_new();
_this->udev = _this->syms.udev_new();
if (_this->udev == NULL) {
SDL_UDEV_Quit();
return SDL_SetError("udev_new() failed");
}
_this->udev_mon = _this->udev_monitor_new_from_netlink(_this->udev, "udev");
_this->udev_mon = _this->syms.udev_monitor_new_from_netlink(_this->udev, "udev");
if (_this->udev_mon == NULL) {
SDL_UDEV_Quit();
return SDL_SetError("udev_monitor_new_from_netlink() failed");
}
_this->udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "input", NULL);
_this->udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "sound", NULL);
_this->udev_monitor_enable_receiving(_this->udev_mon);
_this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "input", NULL);
_this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "sound", NULL);
_this->syms.udev_monitor_enable_receiving(_this->udev_mon);
/* Do an initial scan of existing devices */
SDL_UDEV_Scan();
@ -170,11 +170,11 @@ SDL_UDEV_Quit(void)
if (_this->ref_count < 1) {
if (_this->udev_mon != NULL) {
_this->udev_monitor_unref(_this->udev_mon);
_this->syms.udev_monitor_unref(_this->udev_mon);
_this->udev_mon = NULL;
}
if (_this->udev != NULL) {
_this->udev_unref(_this->udev);
_this->syms.udev_unref(_this->udev);
_this->udev = NULL;
}
@ -202,28 +202,28 @@ SDL_UDEV_Scan(void)
return;
}
enumerate = _this->udev_enumerate_new(_this->udev);
enumerate = _this->syms.udev_enumerate_new(_this->udev);
if (enumerate == NULL) {
SDL_UDEV_Quit();
SDL_SetError("udev_enumerate_new() failed");
return;
}
_this->udev_enumerate_add_match_subsystem(enumerate, "input");
_this->udev_enumerate_add_match_subsystem(enumerate, "sound");
_this->syms.udev_enumerate_add_match_subsystem(enumerate, "input");
_this->syms.udev_enumerate_add_match_subsystem(enumerate, "sound");
_this->udev_enumerate_scan_devices(enumerate);
devs = _this->udev_enumerate_get_list_entry(enumerate);
for (item = devs; item; item = _this->udev_list_entry_get_next(item)) {
const char *path = _this->udev_list_entry_get_name(item);
struct udev_device *dev = _this->udev_device_new_from_syspath(_this->udev, path);
_this->syms.udev_enumerate_scan_devices(enumerate);
devs = _this->syms.udev_enumerate_get_list_entry(enumerate);
for (item = devs; item; item = _this->syms.udev_list_entry_get_next(item)) {
const char *path = _this->syms.udev_list_entry_get_name(item);
struct udev_device *dev = _this->syms.udev_device_new_from_syspath(_this->udev, path);
if (dev != NULL) {
device_event(SDL_UDEV_DEVICEADDED, dev);
_this->udev_device_unref(dev);
_this->syms.udev_device_unref(dev);
}
}
_this->udev_enumerate_unref(enumerate);
_this->syms.udev_enumerate_unref(enumerate);
}
@ -305,7 +305,7 @@ static void get_caps(struct udev_device *dev, struct udev_device *pdev, const ch
unsigned long v;
SDL_memset(bitmask, 0, bitmask_len*sizeof(*bitmask));
value = _this->udev_device_get_sysattr_value(pdev, attr);
value = _this->syms.udev_device_get_sysattr_value(pdev, attr);
if (!value) {
return;
}
@ -340,8 +340,8 @@ guess_device_class(struct udev_device *dev)
/* walk up the parental chain until we find the real input device; the
* argument is very likely a subdevice of this, like eventN */
pdev = dev;
while (pdev && !_this->udev_device_get_sysattr_value(pdev, "capabilities/ev")) {
pdev = _this->udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL);
while (pdev && !_this->syms.udev_device_get_sysattr_value(pdev, "capabilities/ev")) {
pdev = _this->syms.udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL);
}
if (!pdev) {
return 0;
@ -405,28 +405,28 @@ device_event(SDL_UDEV_deviceevent type, struct udev_device *dev)
const char *path;
SDL_UDEV_CallbackList *item;
path = _this->udev_device_get_devnode(dev);
path = _this->syms.udev_device_get_devnode(dev);
if (path == NULL) {
return;
}
subsystem = _this->udev_device_get_subsystem(dev);
subsystem = _this->syms.udev_device_get_subsystem(dev);
if (SDL_strcmp(subsystem, "sound") == 0) {
devclass = SDL_UDEV_DEVICE_SOUND;
} else if (SDL_strcmp(subsystem, "input") == 0) {
/* udev rules reference: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c */
val = _this->udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK");
val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK");
if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
devclass |= SDL_UDEV_DEVICE_JOYSTICK;
}
val = _this->udev_device_get_property_value(dev, "ID_INPUT_MOUSE");
val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_MOUSE");
if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
devclass |= SDL_UDEV_DEVICE_MOUSE;
}
val = _this->udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN");
val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN");
if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN;
}
@ -437,14 +437,14 @@ device_event(SDL_UDEV_deviceevent type, struct udev_device *dev)
Ref: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c#n183
*/
val = _this->udev_device_get_property_value(dev, "ID_INPUT_KEY");
val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_KEY");
if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
devclass |= SDL_UDEV_DEVICE_KEYBOARD;
}
if (devclass == 0) {
/* Fall back to old style input classes */
val = _this->udev_device_get_property_value(dev, "ID_CLASS");
val = _this->syms.udev_device_get_property_value(dev, "ID_CLASS");
if (val != NULL) {
if (SDL_strcmp(val, "joystick") == 0) {
devclass = SDL_UDEV_DEVICE_JOYSTICK;
@ -481,11 +481,11 @@ SDL_UDEV_Poll(void)
}
while (SDL_UDEV_hotplug_update_available()) {
dev = _this->udev_monitor_receive_device(_this->udev_mon);
dev = _this->syms.udev_monitor_receive_device(_this->udev_mon);
if (dev == NULL) {
break;
}
action = _this->udev_device_get_action(dev);
action = _this->syms.udev_device_get_action(dev);
if (SDL_strcmp(action, "add") == 0) {
/* Wait for the device to finish initialization */
@ -496,7 +496,7 @@ SDL_UDEV_Poll(void)
device_event(SDL_UDEV_DEVICEREMOVED, dev);
}
_this->udev_device_unref(dev);
_this->syms.udev_device_unref(dev);
}
}
@ -547,6 +547,22 @@ SDL_UDEV_DelCallback(SDL_UDEV_Callback cb)
}
const SDL_UDEV_Symbols *
SDL_UDEV_GetUdevSyms(void)
{
if (SDL_UDEV_Init() < 0) {
SDL_SetError("Could not initialize UDEV");
return NULL;
}
return &_this->syms;
}
void
SDL_UDEV_ReleaseUdevSyms(void)
{
SDL_UDEV_Quit();
}
#endif /* SDL_USE_LIBUDEV */

View File

@ -64,22 +64,13 @@ typedef struct SDL_UDEV_CallbackList {
struct SDL_UDEV_CallbackList *next;
} SDL_UDEV_CallbackList;
typedef struct SDL_UDEV_PrivateData
{
const char *udev_library;
void *udev_handle;
struct udev *udev;
struct udev_monitor *udev_mon;
int ref_count;
SDL_UDEV_CallbackList *first, *last;
/* Function pointers */
typedef struct SDL_UDEV_Symbols {
const char *(*udev_device_get_action)(struct udev_device *);
const char *(*udev_device_get_devnode)(struct udev_device *);
const char *(*udev_device_get_subsystem)(struct udev_device *);
struct udev_device *(*udev_device_get_parent_with_subsystem_devtype)(struct udev_device *udev_device, const char *subsystem, const char *devtype);
struct udev_device *(*udev_device_get_parent_with_subsystem_devtype)(struct udev_device *udev_device, const char *subsystem, const char *devtype);
const char *(*udev_device_get_property_value)(struct udev_device *, const char *);
const char *(*udev_device_get_sysattr_value)(struct udev_device *udev_device, const char *sysattr);
const char *(*udev_device_get_sysattr_value)(struct udev_device *udev_device, const char *sysattr);
struct udev_device *(*udev_device_new_from_syspath)(struct udev *, const char *);
void (*udev_device_unref)(struct udev_device *);
int (*udev_enumerate_add_match_property)(struct udev_enumerate *, const char *, const char *);
@ -100,6 +91,19 @@ typedef struct SDL_UDEV_PrivateData
void (*udev_unref)(struct udev *);
struct udev_device * (*udev_device_new_from_devnum)(struct udev *udev, char type, dev_t devnum);
dev_t (*udev_device_get_devnum) (struct udev_device *udev_device);
} SDL_UDEV_Symbols;
typedef struct SDL_UDEV_PrivateData
{
const char *udev_library;
void *udev_handle;
struct udev *udev;
struct udev_monitor *udev_mon;
int ref_count;
SDL_UDEV_CallbackList *first, *last;
/* Function pointers */
SDL_UDEV_Symbols syms;
} SDL_UDEV_PrivateData;
extern int SDL_UDEV_Init(void);
@ -110,8 +114,8 @@ extern void SDL_UDEV_Poll(void);
extern void SDL_UDEV_Scan(void);
extern int SDL_UDEV_AddCallback(SDL_UDEV_Callback cb);
extern void SDL_UDEV_DelCallback(SDL_UDEV_Callback cb);
extern const SDL_UDEV_Symbols *SDL_UDEV_GetUdevSyms(void);
extern void SDL_UDEV_ReleaseUdevSyms(void);
#endif /* HAVE_LIBUDEV_H */

View File

@ -44,7 +44,7 @@ SDL_bool WINRT_XAMLWasEnabled = SDL_FALSE;
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
extern "C"
ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative = NULL;
static Windows::Foundation::EventRegistrationToken WINRT_XAMLAppEventToken;
static Windows::Foundation::EventRegistrationToken WINRT_XAMLAppEventToken;
#endif

View File

@ -22,6 +22,7 @@
#include "SDL_config.h"
#else
#include "../SDL_internal.h"
#include "SDL_simd.h"
#endif
#if defined(__WIN32__)

View File

@ -27,6 +27,7 @@
#if defined(__OS2__)
#define INCL_DOS
#define INCL_DOSERRORS
#include <os2.h>
#include <dos.h>
#endif

View File

@ -696,6 +696,11 @@
#define SDL_SensorUpdate SDL_SensorUpdate_REAL
#define SDL_IsTablet SDL_IsTablet_REAL
#define SDL_GetDisplayOrientation SDL_GetDisplayOrientation_REAL
#define SDL_HasColorKey SDL_HasColorKey_REAL
#define SDL_CreateThreadWithStackSize SDL_CreateThreadWithStackSize_REAL
#define SDL_JoystickGetDevicePlayerIndex SDL_JoystickGetDevicePlayerIndex_REAL
#define SDL_JoystickGetPlayerIndex SDL_JoystickGetPlayerIndex_REAL
#define SDL_GameControllerGetPlayerIndex SDL_GameControllerGetPlayerIndex_REAL
#define SDL_RenderFlush SDL_RenderFlush_REAL
#define SDL_RenderDrawPointF SDL_RenderDrawPointF_REAL
#define SDL_RenderDrawPointsF SDL_RenderDrawPointsF_REAL

View File

@ -738,6 +738,23 @@ SDL_DYNAPI_PROC(void,SDL_SensorClose,(SDL_Sensor *a),(a),)
SDL_DYNAPI_PROC(void,SDL_SensorUpdate,(void),(),)
SDL_DYNAPI_PROC(SDL_bool,SDL_IsTablet,(void),(),return)
SDL_DYNAPI_PROC(SDL_DisplayOrientation,SDL_GetDisplayOrientation,(int a),(a),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasColorKey,(SDL_Surface *a),(a),return)
#ifdef SDL_CreateThreadWithStackSize
#undef SDL_CreateThreadWithStackSize
#endif
#if defined(__WIN32__) && !defined(HAVE_LIBC)
SDL_DYNAPI_PROC(SDL_Thread*,SDL_CreateThreadWithStackSize,(SDL_ThreadFunction a, const char *b, const size_t c, void *d, pfnSDL_CurrentBeginThread e, pfnSDL_CurrentEndThread f),(a,b,c,d,e,f),return)
#elif defined(__OS2__)
SDL_DYNAPI_PROC(SDL_Thread*,SDL_CreateThreadWithStackSize,(SDL_ThreadFunction a, const char *b, const size_t c, void *d, pfnSDL_CurrentBeginThread e, pfnSDL_CurrentEndThread f),(a,b,c,d,e,f),return)
#else
SDL_DYNAPI_PROC(SDL_Thread*,SDL_CreateThreadWithStackSize,(SDL_ThreadFunction a, const char *b, const size_t c, void *d),(a,b,c,d),return)
#endif
SDL_DYNAPI_PROC(int,SDL_JoystickGetDevicePlayerIndex,(int a),(a),return)
SDL_DYNAPI_PROC(int,SDL_JoystickGetPlayerIndex,(SDL_Joystick *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GameControllerGetPlayerIndex,(SDL_GameController *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_RenderFlush,(SDL_Renderer *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_RenderDrawPointF,(SDL_Renderer *a, float b, float c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_RenderDrawPointsF,(SDL_Renderer *a, const SDL_FPoint *b, int c),(a,b,c),return)

View File

@ -417,8 +417,10 @@ SDL_StartEventLoop(void)
SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE);
SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE);
SDL_EventState(SDL_SYSWMEVENT, SDL_DISABLE);
#if 0 /* Leave these events enabled so apps can respond to items being dragged onto them at startup */
SDL_EventState(SDL_DROPFILE, SDL_DISABLE);
SDL_EventState(SDL_DROPTEXT, SDL_DISABLE);
#endif
SDL_AtomicSet(&SDL_EventQ.active, 1);

View File

@ -18,6 +18,10 @@
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_events_c_h_
#define SDL_events_c_h_
#include "../SDL_internal.h"
/* Useful functions and variables from SDL_events.c */
@ -49,4 +53,6 @@ extern void SDL_QuitQuit(void);
extern void SDL_SendPendingQuit(void);
#endif /* SDL_events_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -33,12 +33,38 @@
/* The mouse state */
static SDL_Mouse SDL_mouse;
static Uint32 SDL_double_click_time = 500;
static int SDL_double_click_radius = 1;
static int
SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y);
static void SDLCALL
SDL_MouseDoubleClickTimeChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
if (hint && *hint) {
mouse->double_click_time = SDL_atoi(hint);
} else {
#ifdef __WIN32__
mouse->double_click_time = GetDoubleClickTime();
#else
mouse->double_click_time = 500;
#endif
}
}
static void SDLCALL
SDL_MouseDoubleClickRadiusChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
if (hint && *hint) {
mouse->double_click_radius = SDL_atoi(hint);
} else {
mouse->double_click_radius = 32; /* 32 pixels seems about right for touch interfaces */
}
}
static void SDLCALL
SDL_MouseNormalSpeedScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
@ -83,6 +109,12 @@ SDL_MouseInit(void)
SDL_zerop(mouse);
SDL_AddHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_TIME,
SDL_MouseDoubleClickTimeChanged, mouse);
SDL_AddHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS,
SDL_MouseDoubleClickRadiusChanged, mouse);
SDL_AddHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE,
SDL_MouseNormalSpeedScaleChanged, mouse);
@ -114,12 +146,6 @@ SDL_GetMouse(void)
return &SDL_mouse;
}
void
SDL_SetDoubleClickTime(Uint32 interval)
{
SDL_double_click_time = interval;
}
SDL_Window *
SDL_GetMouseFocus(void)
{
@ -454,9 +480,9 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state
if (state == SDL_PRESSED) {
Uint32 now = SDL_GetTicks();
if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + SDL_double_click_time) ||
SDL_abs(mouse->x - clickstate->last_x) > SDL_double_click_radius ||
SDL_abs(mouse->y - clickstate->last_y) > SDL_double_click_radius) {
if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + mouse->double_click_time) ||
SDL_abs(mouse->x - clickstate->last_x) > mouse->double_click_radius ||
SDL_abs(mouse->y - clickstate->last_y) > mouse->double_click_radius) {
clickstate->click_count = 0;
}
clickstate->last_timestamp = now;

View File

@ -90,6 +90,8 @@ typedef struct
float relative_speed_scale;
float scale_accum_x;
float scale_accum_y;
Uint32 double_click_time;
int double_click_radius;
SDL_bool touch_mouse_events;
/* Data for double-click tracking */
@ -112,9 +114,6 @@ extern int SDL_MouseInit(void);
/* Get the mouse state structure */
SDL_Mouse *SDL_GetMouse(void);
/* Set the default double-click interval */
extern void SDL_SetDoubleClickTime(Uint32 interval);
/* Set the default mouse cursor */
extern void SDL_SetDefaultCursor(SDL_Cursor * cursor);

View File

@ -28,26 +28,13 @@
static int SDLCALL
RemovePendingResizedEvents(void * userdata, SDL_Event *event)
RemovePendingSizeChangedAndResizedEvents(void * userdata, SDL_Event *event)
{
SDL_Event *new_event = (SDL_Event *)userdata;
if (event->type == SDL_WINDOWEVENT &&
event->window.event == SDL_WINDOWEVENT_RESIZED &&
event->window.windowID == new_event->window.windowID) {
/* We're about to post a new size event, drop the old one */
return 0;
}
return 1;
}
static int SDLCALL
RemovePendingSizeChangedEvents(void * userdata, SDL_Event *event)
{
SDL_Event *new_event = (SDL_Event *)userdata;
if (event->type == SDL_WINDOWEVENT &&
event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED &&
(event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED ||
event->window.event == SDL_WINDOWEVENT_RESIZED) &&
event->window.windowID == new_event->window.windowID) {
/* We're about to post a new size event, drop the old one */
return 0;
@ -199,11 +186,8 @@ SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1,
event.window.windowID = window->id;
/* Fixes queue overflow with resize events that aren't processed */
if (windowevent == SDL_WINDOWEVENT_RESIZED) {
SDL_FilterEvents(RemovePendingResizedEvents, &event);
}
if (windowevent == SDL_WINDOWEVENT_SIZE_CHANGED) {
SDL_FilterEvents(RemovePendingSizeChangedEvents, &event);
SDL_FilterEvents(RemovePendingSizeChangedAndResizedEvents, &event);
}
if (windowevent == SDL_WINDOWEVENT_MOVED) {
SDL_FilterEvents(RemovePendingMoveEvents, &event);

View File

@ -18,6 +18,10 @@
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef scancodes_xfree86_h_
#define scancodes_xfree86_h_
#include "../../include/SDL_scancode.h"
/* XFree86 key code to SDL scancode mapping table
@ -503,4 +507,6 @@ static const SDL_Scancode xvnc_scancode_table[] = {
/* 80 */ SDL_SCANCODE_F12,
};
#endif /* scancodes_xfree86_h_ */
/* *INDENT-ON* */

View File

@ -389,9 +389,11 @@ SDL_HapticClose(SDL_Haptic * haptic)
void
SDL_HapticQuit(void)
{
while (SDL_haptics) {
SDL_HapticClose(SDL_haptics);
}
SDL_SYS_HapticQuit();
SDL_assert(SDL_haptics == NULL);
SDL_haptics = NULL;
}
/*

View File

@ -19,7 +19,12 @@
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_haptic_c_h_
#define SDL_haptic_c_h_
extern int SDL_HapticInit(void);
extern void SDL_HapticQuit(void);
#endif /* SDL_haptic_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -195,6 +195,10 @@ SDL_SYS_HapticClose(SDL_Haptic * haptic)
void
SDL_SYS_HapticQuit(void)
{
/* We don't have any way to scan for joysticks (and their vibrators) at init, so don't wipe the list
* of joysticks here in case this is a reinit.
*/
#if 0
SDL_hapticlist_item *item = NULL;
SDL_hapticlist_item *next = NULL;
@ -206,6 +210,7 @@ SDL_SYS_HapticQuit(void)
SDL_hapticlist = SDL_hapticlist_tail = NULL;
numhaptics = 0;
return;
#endif
}
@ -230,7 +235,12 @@ int
SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
Uint32 iterations)
{
Android_JNI_HapticRun (((SDL_hapticlist_item *)haptic->hwdata)->device_id, effect->effect.leftright.length);
float large = effect->effect.leftright.large_magnitude / 32767.0f;
float small = effect->effect.leftright.small_magnitude / 32767.0f;
float total = (large * 0.6f) + (small * 0.4f);
Android_JNI_HapticRun (((SDL_hapticlist_item *)haptic->hwdata)->device_id, total, effect->effect.leftright.length);
return 0;
}

View File

@ -801,7 +801,8 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src)
else if (periodic->type == SDL_HAPTIC_SAWTOOTHDOWN)
dest->u.periodic.waveform = FF_SAW_DOWN;
dest->u.periodic.period = CLAMP(periodic->period);
dest->u.periodic.magnitude = periodic->magnitude;
/* Linux expects 0-65535, so multiply by 2 */
dest->u.periodic.magnitude = CLAMP(periodic->magnitude) * 2;
dest->u.periodic.offset = periodic->offset;
/* Linux phase is defined in interval "[0x0000, 0x10000[", corresponds with "[0deg, 360deg[" phase shift. */
dest->u.periodic.phase = ((Uint32)periodic->phase * 0x10000U) / 36000;
@ -908,9 +909,9 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src)
dest->trigger.button = 0;
dest->trigger.interval = 0;
/* Rumble */
dest->u.rumble.strong_magnitude = leftright->large_magnitude;
dest->u.rumble.weak_magnitude = leftright->small_magnitude;
/* Rumble (Linux expects 0-65535, so multiply by 2) */
dest->u.rumble.strong_magnitude = CLAMP(leftright->large_magnitude) * 2;
dest->u.rumble.weak_magnitude = CLAMP(leftright->small_magnitude) * 2;
break;

View File

@ -11,8 +11,13 @@
#include <pthread.h>
#include <errno.h> // For ETIMEDOUT and ECONNRESET
#include <stdlib.h> // For malloc() and free()
#include <string.h> // For memcpy()
#define TAG "hidapi"
// Have error log always available
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
#ifdef DEBUG
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
@ -27,13 +32,15 @@
#define HID_DEVICE_MANAGER_JAVA_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, HIDDeviceManager, function)
#include "../hidapi/hidapi.h"
typedef uint32_t uint32;
typedef uint64_t uint64;
struct hid_device_
{
int nId;
int m_nId;
int m_nDeviceRefCount;
};
static JavaVM *g_JVM;
@ -333,7 +340,7 @@ static jmethodID g_midHIDDeviceManagerSendFeatureReport;
static jmethodID g_midHIDDeviceManagerGetFeatureReport;
static jmethodID g_midHIDDeviceManagerClose;
uint64_t get_timespec_ms( const struct timespec &ts )
static uint64_t get_timespec_ms( const struct timespec &ts )
{
return (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
}
@ -364,12 +371,20 @@ public:
int IncrementRefCount()
{
return ++m_nRefCount;
int nValue;
pthread_mutex_lock( &m_refCountLock );
nValue = ++m_nRefCount;
pthread_mutex_unlock( &m_refCountLock );
return nValue;
}
int DecrementRefCount()
{
return --m_nRefCount;
int nValue;
pthread_mutex_lock( &m_refCountLock );
nValue = --m_nRefCount;
pthread_mutex_unlock( &m_refCountLock );
return nValue;
}
int GetId()
@ -387,19 +402,31 @@ public:
return m_pDevice;
}
int GetDeviceRefCount()
void ExceptionCheck( JNIEnv *env, const char *pszMethodName )
{
return m_nDeviceRefCount;
}
if ( env->ExceptionCheck() )
{
// Get our exception
jthrowable jExcept = env->ExceptionOccurred();
int IncrementDeviceRefCount()
{
return ++m_nDeviceRefCount;
}
// Clear the exception so we can call JNI again
env->ExceptionClear();
int DecrementDeviceRefCount()
{
return --m_nDeviceRefCount;
// Get our exception message
jclass jExceptClass = env->GetObjectClass( jExcept );
jmethodID jMessageMethod = env->GetMethodID( jExceptClass, "getMessage", "()Ljava/lang/String;" );
jstring jMessage = (jstring)( env->CallObjectMethod( jExcept, jMessageMethod ) );
const char *pszMessage = env->GetStringUTFChars( jMessage, NULL );
// ...and log it.
LOGE( "CHIDDevice::%s threw an exception: %s", pszMethodName, pszMessage );
// Cleanup
env->ReleaseStringUTFChars( jMessage, pszMessage );
env->DeleteLocalRef( jMessage );
env->DeleteLocalRef( jExceptClass );
env->DeleteLocalRef( jExcept );
}
}
bool BOpen()
@ -411,6 +438,7 @@ public:
m_bIsWaitingForOpen = false;
m_bOpenResult = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerOpen, m_nId );
ExceptionCheck( env, "BOpen" );
if ( m_bIsWaitingForOpen )
{
@ -445,8 +473,9 @@ public:
}
m_pDevice = new hid_device;
m_pDevice->nId = m_nId;
m_nDeviceRefCount = 1;
m_pDevice->m_nId = m_nId;
m_pDevice->m_nDeviceRefCount = 1;
LOGD("Creating device %d (%p), refCount = 1\n", m_pDevice->m_nId, m_pDevice);
return true;
}
@ -518,6 +547,8 @@ public:
jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendOutputReport, m_nId, pBuf );
ExceptionCheck( env, "SendOutputReport" );
env->DeleteLocalRef( pBuf );
return nRet;
}
@ -531,6 +562,7 @@ public:
jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendFeatureReport, m_nId, pBuf );
ExceptionCheck( env, "SendFeatureReport" );
env->DeleteLocalRef( pBuf );
return nRet;
}
@ -567,6 +599,7 @@ public:
jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
int nRet = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerGetFeatureReport, m_nId, pBuf ) ? 0 : -1;
ExceptionCheck( env, "GetFeatureReport" );
env->DeleteLocalRef( pBuf );
if ( nRet < 0 )
{
@ -625,7 +658,8 @@ public:
pthread_setspecific( g_ThreadKey, (void*)env );
env->CallVoidMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerClose, m_nId );
ExceptionCheck( env, "Close" );
hid_mutex_guard dataLock( &m_dataLock );
m_vecData.clear();
@ -644,12 +678,12 @@ public:
}
private:
pthread_mutex_t m_refCountLock = PTHREAD_MUTEX_INITIALIZER;
int m_nRefCount = 0;
int m_nId = 0;
hid_device_info *m_pInfo = nullptr;
hid_device *m_pDevice = nullptr;
bool m_bIsBLESteamController = false;
int m_nDeviceRefCount = 0;
pthread_mutex_t m_dataLock = PTHREAD_MUTEX_INITIALIZER; // This lock has to be held to access m_vecData
hid_buffer_pool m_vecData;
@ -669,6 +703,7 @@ public:
class CHIDDevice;
static pthread_mutex_t g_DevicesMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t g_DevicesRefCountMutex = PTHREAD_MUTEX_INITIALIZER;
static hid_device_ref<CHIDDevice> g_Devices;
static hid_device_ref<CHIDDevice> FindDevice( int nDeviceId )
@ -696,8 +731,34 @@ static void ThreadDestroyed(void* value)
}
}
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz, jobject callbackHandler)
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, int nDeviceID, jstring sIdentifier, int nVendorId, int nProductId, jstring sSerialNumber, int nReleaseNumber, jstring sManufacturer, jstring sProduct, int nInterface );
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, int nDeviceID);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult)(JNIEnv *env, jobject thiz, int nDeviceID, bool bOpened);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected)(JNIEnv *env, jobject thiz, int nDeviceID);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceFeatureReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz )
{
LOGV( "HIDDeviceRegisterCallback()");
@ -711,11 +772,19 @@ JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallba
__android_log_print(ANDROID_LOG_ERROR, TAG, "Error initializing pthread key");
}
g_HIDDeviceManagerCallbackHandler = env->NewGlobalRef( callbackHandler );
jclass objClass = env->GetObjectClass( callbackHandler );
if ( g_HIDDeviceManagerCallbackHandler != NULL )
{
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackClass );
g_HIDDeviceManagerCallbackClass = NULL;
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackHandler );
g_HIDDeviceManagerCallbackHandler = NULL;
}
g_HIDDeviceManagerCallbackHandler = env->NewGlobalRef( thiz );
jclass objClass = env->GetObjectClass( thiz );
if ( objClass )
{
g_HIDDeviceManagerCallbackClass = reinterpret_cast< jclass >( env->NewGlobalRef(objClass) );
g_HIDDeviceManagerCallbackClass = reinterpret_cast< jclass >( env->NewGlobalRef( objClass ) );
g_midHIDDeviceManagerOpen = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "openDevice", "(I)Z" );
if ( !g_midHIDDeviceManagerOpen )
{
@ -749,8 +818,13 @@ extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz)
{
LOGV("HIDDeviceReleaseCallback");
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackClass );
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackHandler );
if ( env->IsSameObject( thiz, g_HIDDeviceManagerCallbackHandler ) )
{
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackClass );
g_HIDDeviceManagerCallbackClass = NULL;
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackHandler );
g_HIDDeviceManagerCallbackHandler = NULL;
}
}
extern "C"
@ -924,14 +998,18 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bEx
hid_device_ref< CHIDDevice > pDevice;
{
hid_mutex_guard r( &g_DevicesRefCountMutex );
hid_mutex_guard l( &g_DevicesMutex );
for ( hid_device_ref<CHIDDevice> pCurr = g_Devices; pCurr; pCurr = pCurr->next )
{
if ( strcmp( pCurr->GetDeviceInfo()->path, path ) == 0 )
{
if ( pCurr->GetDevice() ) {
pCurr->IncrementDeviceRefCount();
return pCurr->GetDevice();
hid_device *pValue = pCurr->GetDevice();
if ( pValue )
{
++pValue->m_nDeviceRefCount;
LOGD("Incrementing device %d (%p), refCount = %d\n", pValue->m_nId, pValue, pValue->m_nDeviceRefCount);
return pValue;
}
// Hold a shared pointer to the controller for the duration
@ -949,8 +1027,8 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bEx
int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length)
{
LOGV( "hid_write id=%d length=%u", device->nId, length );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId );
LOGV( "hid_write id=%d length=%u", device->m_nId, length );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice )
{
return pDevice->SendOutputReport( data, length );
@ -961,8 +1039,8 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned ch
// TODO: Implement timeout?
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds)
{
// LOGV( "hid_read_timeout id=%d length=%u timeout=%d", device->nId, length, milliseconds );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId );
// LOGV( "hid_read_timeout id=%d length=%u timeout=%d", device->m_nId, length, milliseconds );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice )
{
return pDevice->GetInput( data, length );
@ -974,7 +1052,7 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned ch
// TODO: Implement blocking
int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length)
{
LOGV( "hid_read id=%d length=%u", device->nId, length );
LOGV( "hid_read id=%d length=%u", device->m_nId, length );
return hid_read_timeout( device, data, length, 0 );
}
@ -986,8 +1064,8 @@ int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int non
int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length)
{
LOGV( "hid_send_feature_report id=%d length=%u", device->nId, length );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId );
LOGV( "hid_send_feature_report id=%d length=%u", device->m_nId, length );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice )
{
return pDevice->SendFeatureReport( data, length );
@ -999,8 +1077,8 @@ int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, cons
// Synchronous operation. Will block until completed.
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length)
{
LOGV( "hid_get_feature_report id=%d length=%u", device->nId, length );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId );
LOGV( "hid_get_feature_report id=%d length=%u", device->m_nId, length );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice )
{
return pDevice->GetFeatureReport( data, length );
@ -1011,26 +1089,28 @@ int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsig
void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device)
{
LOGV( "hid_close id=%d", device->nId );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId );
if ( pDevice )
LOGV( "hid_close id=%d", device->m_nId );
hid_mutex_guard r( &g_DevicesRefCountMutex );
LOGD("Decrementing device %d (%p), refCount = %d\n", device->m_nId, device, device->m_nDeviceRefCount - 1);
if ( --device->m_nDeviceRefCount == 0 )
{
pDevice->DecrementDeviceRefCount();
if ( pDevice->GetDeviceRefCount() == 0 ) {
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice )
{
pDevice->Close( true );
}
}
else
{
// Couldn't find it, it's already closed
delete device;
else
{
delete device;
}
LOGD("Deleted device %p\n", device);
}
}
int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen)
{
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice )
{
wcsncpy( string, pDevice->GetDeviceInfo()->manufacturer_string, maxlen );
@ -1041,7 +1121,7 @@ int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t
int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen)
{
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice )
{
wcsncpy( string, pDevice->GetDeviceInfo()->product_string, maxlen );
@ -1052,7 +1132,7 @@ int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *stri
int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen)
{
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice )
{
wcsncpy( string, pDevice->GetDeviceInfo()->serial_number, maxlen );

View File

@ -29,7 +29,7 @@
#include <wchar.h>
#if defined(_WIN32) && !defined(NAMESPACE)
#if defined(_WIN32) && !defined(NAMESPACE) && (0) /* SDL: don't export hidapi syms */
#define HID_API_EXPORT __declspec(dllexport)
#define HID_API_CALL
#else
@ -225,7 +225,7 @@ namespace NAMESPACE {
-1 on error. If no packet was available to be read within
the timeout period, this function returns 0.
*/
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds);
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds);
/** @brief Read an Input report from a HID device.

View File

@ -3,6 +3,9 @@
// Purpose: HID device abstraction temporary stub
//
//=============================================================================
#include "../../SDL_internal.h"
#ifdef SDL_JOYSTICK_HIDAPI
#include <CoreBluetooth/CoreBluetooth.h>
#include <QuartzCore/QuartzCore.h>
@ -907,3 +910,5 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
#endif
return result;
}
#endif /* SDL_JOYSTICK_HIDAPI */

View File

@ -22,6 +22,9 @@
code repository located at:
http://github.com/signal11/hidapi .
********************************************************/
#include "../../SDL_internal.h"
#ifdef SDL_JOYSTICK_HIDAPI
#ifndef _GNU_SOURCE
#define _GNU_SOURCE /* needed for wcsdup() before glibc 2.10 */
@ -1613,3 +1616,5 @@ uint16_t get_usb_code_for_current_locale(void)
#ifdef NAMESPACE
}
#endif
#endif /* SDL_JOYSTICK_HIDAPI */

View File

@ -20,6 +20,9 @@
code repository located at:
http://github.com/signal11/hidapi .
********************************************************/
#include "../../SDL_internal.h"
#ifdef SDL_JOYSTICK_HIDAPI
#ifndef _GNU_SOURCE
#define _GNU_SOURCE /* needed for wcsdup() before glibc 2.10 */
@ -891,3 +894,5 @@ HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
#ifdef NAMESPACE
}
#endif
#endif /* SDL_JOYSTICK_HIDAPI */

View File

@ -19,6 +19,9 @@
code repository located at:
http://github.com/signal11/hidapi .
********************************************************/
#include "../../SDL_internal.h"
#ifdef SDL_JOYSTICK_HIDAPI
/* See Apple Technical Note TN2187 for details on IOHidManager. */
@ -1184,3 +1187,5 @@ int main(void)
return 0;
}
#endif
#endif /* SDL_JOYSTICK_HIDAPI */

View File

@ -19,13 +19,13 @@
code repository located at:
http://github.com/signal11/hidapi .
********************************************************/
#include "../../SDL_internal.h"
#ifdef SDL_JOYSTICK_HIDAPI
#include <windows.h>
#ifndef _NTDEF_
typedef LONG NTSTATUS;
#endif
#if 0 /* can cause redefinition errors on some toolchains */
#ifdef __MINGW32__
#include <ntdef.h>
#include <winbase.h>
@ -35,6 +35,11 @@ typedef LONG NTSTATUS;
#include <ntdef.h>
#define _wcsdup wcsdup
#endif
#endif /* */
#ifndef _NTDEF_
typedef LONG NTSTATUS;
#endif
/* SDL C runtime functions */
#include "SDL_stdinc.h"
@ -905,17 +910,18 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int
return 0;
}
HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
{
return (wchar_t*)dev->last_error_str;
}
#if 0
/*#define PICPGM*/
/*#define S11*/
#define P32
#ifdef S11
#ifdef S11
unsigned short VendorID = 0xa0a0;
unsigned short ProductID = 0x0001;
#endif
@ -925,14 +931,11 @@ HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
unsigned short ProductID = 0x3f;
#endif
#ifdef PICPGM
unsigned short VendorID = 0x04d8;
unsigned short ProductID = 0x0033;
#endif
#if 0
int __cdecl main(int argc, char* argv[])
{
int res;
@ -981,3 +984,5 @@ int __cdecl main(int argc, char* argv[])
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* SDL_JOYSTICK_HIDAPI */

View File

@ -111,7 +111,6 @@ struct _SDL_GameController
SDL_Joystick *joystick; /* underlying joystick device */
int ref_count;
SDL_JoystickGUID guid;
const char *name;
int num_bindings;
SDL_ExtendedGameControllerBind *bindings;
@ -433,12 +432,12 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickG
pSupportedController = pSupportedController->next;
}
if (!exact_match) {
if (guid->data[14] == 'h') {
if (SDL_IsJoystickHIDAPI(*guid)) {
/* This is a HIDAPI device */
return s_pHIDAPIMapping;
}
#if SDL_JOYSTICK_XINPUT
if (guid->data[14] == 'x') {
if (SDL_IsJoystickXInput(*guid)) {
/* This is an XInput device */
return s_pXInputMapping;
}
@ -684,11 +683,10 @@ SDL_PrivateGameControllerParseControllerConfigString(SDL_GameController *gamecon
/*
* Make a new button mapping struct
*/
static void SDL_PrivateLoadButtonMapping(SDL_GameController *gamecontroller, SDL_JoystickGUID guid, const char *pchName, const char *pchMapping)
static void SDL_PrivateLoadButtonMapping(SDL_GameController *gamecontroller, const char *pchName, const char *pchMapping)
{
int i;
gamecontroller->guid = guid;
gamecontroller->name = pchName;
gamecontroller->num_bindings = 0;
SDL_memset(gamecontroller->last_match_axis, 0, gamecontroller->joystick->naxes * sizeof(*gamecontroller->last_match_axis));
@ -802,14 +800,16 @@ static void SDL_PrivateGameControllerRefreshMapping(ControllerMapping_t *pContro
{
SDL_GameController *gamecontrollerlist = SDL_gamecontrollers;
while (gamecontrollerlist) {
if (!SDL_memcmp(&gamecontrollerlist->guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid))) {
SDL_Event event;
event.type = SDL_CONTROLLERDEVICEREMAPPED;
event.cdevice.which = gamecontrollerlist->joystick->instance_id;
SDL_PushEvent(&event);
if (!SDL_memcmp(&gamecontrollerlist->joystick->guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid))) {
/* Not really threadsafe. Should this lock access within SDL_GameControllerEventWatcher? */
SDL_PrivateLoadButtonMapping(gamecontrollerlist, pControllerMapping->guid, pControllerMapping->name, pControllerMapping->mapping);
SDL_PrivateLoadButtonMapping(gamecontrollerlist, pControllerMapping->name, pControllerMapping->mapping);
{
SDL_Event event;
event.type = SDL_CONTROLLERDEVICEREMAPPED;
event.cdevice.which = gamecontrollerlist->joystick->instance_id;
SDL_PushEvent(&event);
}
}
gamecontrollerlist = gamecontrollerlist->next;
@ -1027,7 +1027,7 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForNameAndGUID(const
}
}
#ifdef __ANDROID__
if (!mapping) {
if (!mapping && name && !SDL_IsJoystickHIDAPI(guid)) {
mapping = SDL_CreateMappingForAndroidController(name, guid);
}
#endif
@ -1274,7 +1274,7 @@ SDL_GameControllerMapping(SDL_GameController * gamecontroller)
return NULL;
}
return SDL_GameControllerMappingForGUID(gamecontroller->guid);
return SDL_GameControllerMappingForGUID(gamecontroller->joystick->guid);
}
static void
@ -1463,6 +1463,7 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
int i;
Uint16 vendor;
Uint16 product;
Uint16 version;
Uint32 vidpid;
if (SDL_allowed_controllers.num_entries == 0 &&
@ -1470,7 +1471,7 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
return SDL_FALSE;
}
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, &version);
if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE)) {
/* We shouldn't ignore Steam's virtual gamepad since it's using the hints to filter out the real controllers so it can remap input for the virtual controller */
@ -1478,7 +1479,7 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
#if defined(__LINUX__)
bSteamVirtualGamepad = (vendor == 0x28DE && product == 0x11FF);
#elif defined(__MACOSX__)
bSteamVirtualGamepad = (SDL_strncmp(name, "GamePad-", 8) == 0);
bSteamVirtualGamepad = (vendor == 0x045E && product == 0x028E && version == 1);
#elif defined(__WIN32__)
/* We can't tell on Windows, but Steam will block others in input hooks */
bSteamVirtualGamepad = SDL_TRUE;
@ -1582,7 +1583,7 @@ SDL_GameControllerOpen(int device_index)
}
}
SDL_PrivateLoadButtonMapping(gamecontroller, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping);
SDL_PrivateLoadButtonMapping(gamecontroller, pSupportedController->name, pSupportedController->mapping);
/* Add the controller to list */
++gamecontroller->ref_count;
@ -1716,6 +1717,12 @@ SDL_GameControllerName(SDL_GameController * gamecontroller)
}
}
int
SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller)
{
return SDL_JoystickGetPlayerIndex(SDL_GameControllerGetJoystick(gamecontroller));
}
Uint16
SDL_GameControllerGetVendor(SDL_GameController * gamecontroller)
{

View File

@ -362,6 +362,7 @@ static const char *s_ControllerMappings [] =
"03000000022000000090000011010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,",
"05000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,",
"05000000c82d00002038000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,",
"05000000c82d00000061000000010000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,",
"05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,",
"05000000c82d00003028000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,",
"05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,",
@ -548,6 +549,7 @@ static const char *s_ControllerMappings [] =
"0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
"050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"030000005e040000ea02000001030000,Xbox One Wireless Controller (Model 1708),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,",
"03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,",
"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",

View File

@ -227,6 +227,21 @@ SDL_JoystickNameForIndex(int device_index)
return name;
}
int
SDL_JoystickGetDevicePlayerIndex(int device_index)
{
SDL_JoystickDriver *driver;
int player_index = -1;
SDL_LockJoysticks();
if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) {
player_index = driver->GetDevicePlayerIndex(device_index);
}
SDL_UnlockJoysticks();
return player_index;
}
/*
* Return true if this joystick is known to have all axes centered at zero
* This isn't generally needed unless the joystick never generates an initial axis value near zero,
@ -307,6 +322,7 @@ SDL_JoystickOpen(int device_index)
joystick->driver = driver;
joystick->instance_id = instance_id;
joystick->attached = SDL_TRUE;
joystick->player_index = -1;
if (driver->Open(joystick, device_index) < 0) {
SDL_free(joystick);
@ -602,6 +618,15 @@ SDL_JoystickName(SDL_Joystick * joystick)
return SDL_FixupJoystickName(joystick->name);
}
int
SDL_JoystickGetPlayerIndex(SDL_Joystick * joystick)
{
if (!SDL_PrivateJoystickValid(joystick)) {
return -1;
}
return joystick->player_index;
}
int
SDL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
{
@ -1136,19 +1161,19 @@ SDL_IsJoystickNintendoSwitchPro(Uint16 vendor, Uint16 product)
SDL_bool
SDL_IsJoystickSteamController(Uint16 vendor, Uint16 product)
{
return BIsSteamController(GuessControllerType(vendor, product)) ? SDL_TRUE : SDL_FALSE;
return BIsSteamController(GuessControllerType(vendor, product));
}
SDL_bool
SDL_IsJoystickXbox360(Uint16 vendor, Uint16 product)
{
/* Filter out some bogus values here */
if (vendor == 0x0000 && product == 0x0000) {
return SDL_FALSE;
}
if (vendor == 0x0001 && product == 0x0001) {
return SDL_FALSE;
}
/* Filter out some bogus values here */
if (vendor == 0x0000 && product == 0x0000) {
return SDL_FALSE;
}
if (vendor == 0x0001 && product == 0x0001) {
return SDL_FALSE;
}
return (GuessControllerType(vendor, product) == k_eControllerType_XBox360Controller);
}
@ -1158,6 +1183,18 @@ SDL_IsJoystickXboxOne(Uint16 vendor, Uint16 product)
return (GuessControllerType(vendor, product) == k_eControllerType_XBoxOneController);
}
SDL_bool
SDL_IsJoystickXInput(SDL_JoystickGUID guid)
{
return (guid.data[14] == 'x') ? SDL_TRUE : SDL_FALSE;
}
SDL_bool
SDL_IsJoystickHIDAPI(SDL_JoystickGUID guid)
{
return (guid.data[14] == 'h') ? SDL_TRUE : SDL_FALSE;
}
static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
{
static Uint32 wheel_joysticks[] = {
@ -1223,7 +1260,7 @@ static SDL_JoystickType SDL_GetJoystickGUIDType(SDL_JoystickGUID guid)
Uint16 product;
Uint32 vidpid;
if (guid.data[14] == 'x') {
if (SDL_IsJoystickXInput(guid)) {
/* XInput GUID, get the type based on the XInput device subtype */
switch (guid.data[15]) {
case 0x01: /* XINPUT_DEVSUBTYPE_GAMEPAD */

View File

@ -18,6 +18,10 @@
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_joystick_c_h_
#define SDL_joystick_c_h_
#include "../SDL_internal.h"
/* Useful functions and variables from SDL_joystick.c */
@ -62,6 +66,12 @@ extern SDL_bool SDL_IsJoystickXbox360(Uint16 vendor_id, Uint16 product_id);
/* Function to return whether a joystick is an Xbox One controller */
extern SDL_bool SDL_IsJoystickXboxOne(Uint16 vendor_id, Uint16 product_id);
/* Function to return whether a joystick guid comes from the XInput driver */
extern SDL_bool SDL_IsJoystickXInput(SDL_JoystickGUID guid);
/* Function to return whether a joystick guid comes from the HIDAPI driver */
extern SDL_bool SDL_IsJoystickHIDAPI(SDL_JoystickGUID guid);
/* Function to return whether a joystick should be ignored */
extern SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid);
@ -91,4 +101,6 @@ extern void SDL_PrivateJoystickBatteryLevel(SDL_Joystick * joystick,
/* Internal sanity checking functions */
extern int SDL_PrivateJoystickValid(SDL_Joystick * joystick);
#endif /* SDL_joystick_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -42,6 +42,7 @@ struct _SDL_Joystick
{
SDL_JoystickID instance_id; /* Device instance, monotonically increasing from 0 */
char *name; /* Joystick name - system dependent */
int player_index; /* Joystick player index, or -1 if unavailable */
SDL_JoystickGUID guid; /* Joystick guid */
int naxes; /* Number of axis controls on the joystick */
@ -105,6 +106,9 @@ typedef struct _SDL_JoystickDriver
/* Function to get the device-dependent name of a joystick */
const char *(*GetDeviceName)(int device_index);
/* Function to get the player index of a joystick */
int (*GetDevicePlayerIndex)(int device_index);
/* Function to return the stable GUID for a plugged in device */
SDL_JoystickGUID (*GetDeviceGUID)(int device_index);

View File

@ -581,6 +581,12 @@ ANDROID_JoystickGetDeviceName(int device_index)
return JoystickByDevIndex(device_index)->name;
}
static int
ANDROID_JoystickGetDevicePlayerIndex(int device_index)
{
return -1;
}
static SDL_JoystickGUID
ANDROID_JoystickGetDeviceGUID(int device_index)
{
@ -689,6 +695,7 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver =
ANDROID_JoystickGetCount,
ANDROID_JoystickDetect,
ANDROID_JoystickGetDeviceName,
ANDROID_JoystickGetDevicePlayerIndex,
ANDROID_JoystickGetDeviceGUID,
ANDROID_JoystickGetDeviceInstanceID,
ANDROID_JoystickOpen,

Some files were not shown because too many files have changed in this diff Show More