├── .appveyor.yml ├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── Doxyfile ├── LICENSE ├── README.md ├── build.gradle ├── extern ├── android │ ├── AndroidManifest.xml │ └── res │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml ├── catch │ └── catch.hpp ├── cmake │ ├── AndroidNdkModules.cmake │ ├── android.toolchain.cmake │ └── iOS.cmake └── ios │ ├── Info.plist │ └── Launch Screen.storyboard ├── lib ├── CMakeLists.txt ├── include │ └── gainput │ │ ├── GainputAllocator.h │ │ ├── GainputContainers.h │ │ ├── GainputDebugRenderer.h │ │ ├── GainputHelpers.h │ │ ├── GainputInputDeltaState.h │ │ ├── GainputInputDevice.h │ │ ├── GainputInputDeviceBuiltIn.h │ │ ├── GainputInputDeviceKeyboard.h │ │ ├── GainputInputDeviceMouse.h │ │ ├── GainputInputDevicePad.h │ │ ├── GainputInputDeviceTouch.h │ │ ├── GainputInputListener.h │ │ ├── GainputInputManager.h │ │ ├── GainputInputMap.h │ │ ├── GainputInputState.h │ │ ├── GainputIos.h │ │ ├── GainputLog.h │ │ ├── GainputMapFilters.h │ │ ├── gainput.h │ │ ├── gestures │ │ ├── GainputButtonStickGesture.h │ │ ├── GainputDoubleClickGesture.h │ │ ├── GainputGestures.h │ │ ├── GainputHoldGesture.h │ │ ├── GainputPinchGesture.h │ │ ├── GainputRotateGesture.h │ │ ├── GainputSimultaneouslyDownGesture.h │ │ └── GainputTapGesture.h │ │ └── recorder │ │ ├── GainputInputPlayer.h │ │ ├── GainputInputRecorder.h │ │ └── GainputInputRecording.h ├── java │ ├── com │ │ └── example │ │ │ └── gainput │ │ │ └── gainput │ │ │ └── BasicActivity.java │ └── de │ │ └── johanneskuhlmann │ │ └── gainput │ │ └── Gainput.java └── source │ └── gainput │ ├── GainputAllocator.cpp │ ├── GainputHelpersEvdev.h │ ├── GainputInputDeltaState.cpp │ ├── GainputInputDevice.cpp │ ├── GainputInputManager.cpp │ ├── GainputInputMap.cpp │ ├── GainputInputState.cpp │ ├── GainputIos.mm │ ├── GainputMac.mm │ ├── GainputMapFilters.cpp │ ├── GainputWindows.h │ ├── builtin │ ├── GainputInputDeviceBuiltIn.cpp │ ├── GainputInputDeviceBuiltInAndroid.h │ ├── GainputInputDeviceBuiltInImpl.h │ ├── GainputInputDeviceBuiltInIos.h │ ├── GainputInputDeviceBuiltInIos.mm │ └── GainputInputDeviceBuiltInNull.h │ ├── dev │ ├── GainputDev.cpp │ ├── GainputDev.h │ ├── GainputDevProtocol.h │ ├── GainputMemoryStream.cpp │ ├── GainputMemoryStream.h │ ├── GainputNetAddress.cpp │ ├── GainputNetAddress.h │ ├── GainputNetConnection.cpp │ ├── GainputNetConnection.h │ ├── GainputNetListener.cpp │ ├── GainputNetListener.h │ └── GainputStream.h │ ├── gainput.cpp │ ├── gestures │ ├── GainputButtonStickGesture.cpp │ ├── GainputDoubleClickGesture.cpp │ ├── GainputHoldGesture.cpp │ ├── GainputPinchGesture.cpp │ ├── GainputRotateGesture.cpp │ ├── GainputSimultaneouslyDownGesture.cpp │ └── GainputTapGesture.cpp │ ├── keyboard │ ├── GainputInputDeviceKeyboard.cpp │ ├── GainputInputDeviceKeyboardAndroid.h │ ├── GainputInputDeviceKeyboardEvdev.h │ ├── GainputInputDeviceKeyboardImpl.h │ ├── GainputInputDeviceKeyboardLinux.h │ ├── GainputInputDeviceKeyboardMac.cpp │ ├── GainputInputDeviceKeyboardMac.h │ ├── GainputInputDeviceKeyboardNull.h │ ├── GainputInputDeviceKeyboardWin.h │ ├── GainputInputDeviceKeyboardWinRaw.h │ └── GainputKeyboardKeyNames.h │ ├── mouse │ ├── GainputInputDeviceMouse.cpp │ ├── GainputInputDeviceMouseEvdev.h │ ├── GainputInputDeviceMouseImpl.h │ ├── GainputInputDeviceMouseLinux.h │ ├── GainputInputDeviceMouseMac.h │ ├── GainputInputDeviceMouseMac.mm │ ├── GainputInputDeviceMouseNull.h │ ├── GainputInputDeviceMouseWin.h │ ├── GainputInputDeviceMouseWinRaw.h │ └── GainputMouseInfo.h │ ├── pad │ ├── GainputInputDevicePad.cpp │ ├── GainputInputDevicePadAndroid.h │ ├── GainputInputDevicePadImpl.h │ ├── GainputInputDevicePadIos.h │ ├── GainputInputDevicePadIos.mm │ ├── GainputInputDevicePadLinux.h │ ├── GainputInputDevicePadMac.cpp │ ├── GainputInputDevicePadMac.h │ ├── GainputInputDevicePadNull.h │ └── GainputInputDevicePadWin.h │ ├── recorder │ ├── GainputInputPlayer.cpp │ ├── GainputInputRecorder.cpp │ └── GainputInputRecording.cpp │ └── touch │ ├── GainputInputDeviceTouch.cpp │ ├── GainputInputDeviceTouchAndroid.h │ ├── GainputInputDeviceTouchImpl.h │ ├── GainputInputDeviceTouchIos.h │ ├── GainputInputDeviceTouchNull.h │ └── GainputTouchInfo.h ├── samples ├── CMakeLists.txt ├── android │ ├── AndroidManifest.xml │ ├── project.properties │ └── res │ │ └── values │ │ └── strings.xml ├── basic │ ├── CMakeLists.txt │ ├── basicsample_android.cpp │ ├── basicsample_android_generic.cpp │ ├── basicsample_ios.mm │ ├── basicsample_linux.cpp │ ├── basicsample_mac.mm │ └── basicsample_win.cpp ├── dynamic │ ├── CMakeLists.txt │ └── dynamicsample.cpp ├── gesture │ ├── CMakeLists.txt │ └── gesturesample.cpp ├── listener │ ├── CMakeLists.txt │ └── listenersample.cpp ├── recording │ ├── CMakeLists.txt │ └── recordingsample.cpp ├── samplefw │ ├── SampleFramework.cpp │ └── SampleFramework.h └── sync │ ├── CMakeLists.txt │ └── syncsample.cpp ├── test ├── CMakeLists.txt ├── test.cpp ├── test_inputdevice.cpp ├── test_inputmanager.cpp ├── test_inputmap.cpp ├── test_inputrecording.cpp └── test_inputstate.cpp └── tools └── html5client ├── index.html └── touch.html /.appveyor.yml: -------------------------------------------------------------------------------- 1 | 2 | platform: 3 | - x64 4 | 5 | configuration: 6 | - Debug 7 | - Release 8 | 9 | before_build: 10 | - md build 11 | - cd build 12 | - cmake -G "Visual Studio 14 2015 Win64" .. 13 | 14 | build: 15 | project: build\Project.sln 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.[doa] 2 | *.swp 3 | *.mk 4 | *.pyc 5 | .lock-* 6 | .cproject 7 | .project 8 | build/ 9 | __pycache__/ 10 | .depproj/ 11 | gainput_2008.* 12 | docs/ 13 | gainput.sdf 14 | gainput.sln 15 | gainput.unsuccessfulbuild 16 | *.opensdf 17 | cmakebuild*/ 18 | 19 | .idea 20 | .gradle 21 | .externalNativeBuild 22 | gradle 23 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | os: 2 | - linux 3 | - osx 4 | language: cpp 5 | compiler: 6 | - gcc 7 | - clang 8 | sudo: false 9 | script: mkdir build_debug && cd build_debug/ && cmake -DCMAKE_BUILD_TYPE=Debug .. && make && test/gainputtest && cd .. && mkdir build_release && cd build_release/ && cmake -DCMAKE_BUILD_TYPE=Release .. && make && test/gainputtest 10 | 11 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | set(GAINPUT_MAJOR_VERSION 1) 3 | set(GAINPUT_MINOR_VERSION 0) 4 | set(GAINPUT_PATCH_VERSION 0) 5 | set(GAINPUT_VERSION ${GAINPUT_MAJOR_VERSION}.${GAINPUT_MINOR_VERSION}.${GAINPUT_PATCH_VERSION}) 6 | 7 | option(GAINPUT_SAMPLES "Build Samples for Gainput" ON) 8 | option(GAINPUT_TESTS "Build Tests for Gainput" ON) 9 | option(GAINPUT_BUILD_SHARED "BUILD_SHARED" ON) 10 | option(GAINPUT_BUILD_STATIC "BUILD_STATIC" ON) 11 | 12 | if(!WIN32) 13 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -Wextra") 14 | else() 15 | set(XINPUT "Xinput9_1_0") 16 | if ( ${CMAKE_SYSTEM_VERSION} LESS 6.1 ) 17 | set(XINPUT, "xinput") 18 | endif() 19 | endif() 20 | 21 | if(ANDROID) 22 | include(extern/cmake/AndroidNdkModules.cmake) 23 | android_ndk_import_module_native_app_glue() 24 | endif() 25 | 26 | add_subdirectory(lib) 27 | 28 | if(GAINPUT_SAMPLES) 29 | add_subdirectory(samples) 30 | endif() 31 | 32 | if(GAINPUT_TESTS) 33 | add_subdirectory(test) 34 | endif() 35 | 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2017 Johannes Kuhlmann 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | jcenter() 4 | } 5 | dependencies { 6 | classpath 'com.android.tools.build:gradle:2.3.2' 7 | 8 | // NOTE: Do not place your application dependencies here; they belong 9 | // in the individual module build.gradle files 10 | } 11 | } 12 | 13 | allprojects { 14 | repositories { 15 | jcenter() 16 | } 17 | } 18 | 19 | apply plugin: 'com.android.application' 20 | 21 | android { 22 | compileSdkVersion 25 23 | buildToolsVersion "25.0.2" 24 | defaultConfig { 25 | applicationId "com.example.gainput.gainput" 26 | minSdkVersion 21 27 | targetSdkVersion 25 28 | versionCode 1 29 | versionName "1.0" 30 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 31 | externalNativeBuild { 32 | cmake { 33 | cppFlags "" 34 | } 35 | } 36 | } 37 | buildTypes { 38 | release { 39 | minifyEnabled false 40 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 41 | } 42 | } 43 | externalNativeBuild { 44 | cmake { 45 | path "CMakeLists.txt" 46 | } 47 | } 48 | sourceSets { 49 | main { 50 | manifest.srcFile 'extern/android/AndroidManifest.xml' 51 | res.srcDirs = ['extern/android/res/'] 52 | java.srcDirs = ['lib/java/'] 53 | } 54 | } 55 | } 56 | 57 | dependencies { 58 | compile fileTree(dir: 'libs', include: ['*.jar']) 59 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 60 | exclude group: 'com.android.support', module: 'support-annotations' 61 | }) 62 | compile 'com.android.support:appcompat-v7:25.3.1' 63 | testCompile 'junit:junit:4.12' 64 | } 65 | -------------------------------------------------------------------------------- /extern/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /extern/android/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkuhlmann/gainput/2be0a50089eafcc6fccb66142180082e48f27f4c/extern/android/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /extern/android/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkuhlmann/gainput/2be0a50089eafcc6fccb66142180082e48f27f4c/extern/android/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /extern/android/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkuhlmann/gainput/2be0a50089eafcc6fccb66142180082e48f27f4c/extern/android/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /extern/android/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkuhlmann/gainput/2be0a50089eafcc6fccb66142180082e48f27f4c/extern/android/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /extern/android/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkuhlmann/gainput/2be0a50089eafcc6fccb66142180082e48f27f4c/extern/android/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /extern/android/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkuhlmann/gainput/2be0a50089eafcc6fccb66142180082e48f27f4c/extern/android/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /extern/android/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkuhlmann/gainput/2be0a50089eafcc6fccb66142180082e48f27f4c/extern/android/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /extern/android/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkuhlmann/gainput/2be0a50089eafcc6fccb66142180082e48f27f4c/extern/android/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /extern/android/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkuhlmann/gainput/2be0a50089eafcc6fccb66142180082e48f27f4c/extern/android/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /extern/android/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkuhlmann/gainput/2be0a50089eafcc6fccb66142180082e48f27f4c/extern/android/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /extern/android/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /extern/android/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Gainput 3 | 4 | -------------------------------------------------------------------------------- /extern/android/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /extern/cmake/AndroidNdkModules.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014, Pavel Rojtberg 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, 8 | # this list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from this 16 | # software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | # POSSIBILITY OF SUCH DAMAGE. 29 | 30 | macro(android_ndk_import_module_cpufeatures) 31 | if(ANDROID) 32 | include_directories(${ANDROID_NDK}/sources/android/cpufeatures) 33 | add_library(cpufeatures ${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c) 34 | target_link_libraries(cpufeatures dl) 35 | endif() 36 | endmacro() 37 | 38 | macro(android_ndk_import_module_native_app_glue) 39 | if(ANDROID) 40 | include_directories(${ANDROID_NDK}/sources/android/native_app_glue) 41 | #include_directories(${ANDROID_NDK}/platforms/android-21/arch-arm/usr/include/) 42 | add_library(native_app_glue ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c) 43 | target_link_libraries(native_app_glue log) 44 | endif() 45 | endmacro() 46 | 47 | macro(android_ndk_import_module_ndk_helper) 48 | if(ANDROID) 49 | android_ndk_import_module_cpufeatures() 50 | android_ndk_import_module_native_app_glue() 51 | 52 | include_directories(${ANDROID_NDK}/sources/android/ndk_helper) 53 | file(GLOB _NDK_HELPER_SRCS ${ANDROID_NDK}/sources/android/ndk_helper/*.cpp ${ANDROID_NDK}/sources/android/ndk_helper/gl3stub.c) 54 | add_library(ndk_helper ${_NDK_HELPER_SRCS}) 55 | target_link_libraries(ndk_helper log android EGL GLESv2 cpufeatures native_app_glue) 56 | 57 | unset(_NDK_HELPER_SRCS) 58 | endif() 59 | endmacro() 60 | -------------------------------------------------------------------------------- /extern/ios/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.example.gainput.$(PRODUCT_NAME:rfc1034identifier) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | Launch Screen 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UIStatusBarHidden 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(gainput) 2 | message(STATUS "GAINPUT version ${GAINPUT_VERSION}") 3 | 4 | set(CMAKE_MACOSX_RPATH 1) 5 | 6 | if(CMAKE_COMPILER_IS_GNUCXX) 7 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++98 -Wall -Wextra -pedantic -Wshadow -Wno-variadic-macros") 8 | endif() 9 | 10 | include_directories (include/) 11 | 12 | file(GLOB_RECURSE sources source/*.cpp source/*.h include/*.h) 13 | 14 | if(APPLE) 15 | file(GLOB_RECURSE mmsources source/*.mm) 16 | endif() 17 | 18 | ## build STATIC *or* SHARED 19 | if (GAINPUT_BUILD_SHARED) 20 | message(STATUS "..Building shared libraries (-DGAINPUT_BUILD_SHARED=OFF to disable)") 21 | add_library(gainput SHARED ${sources} ${mmsources}) 22 | set_target_properties(gainput PROPERTIES 23 | OUTPUT_NAME gainput 24 | DEBUG_POSTFIX -d 25 | VERSION ${GAINPUT_VERSION} 26 | SOVERSION ${GAINPUT_MAJOR_VERSION} 27 | FOLDER gainput 28 | ) 29 | set(install_libs ${install_libs} gainput) 30 | endif (GAINPUT_BUILD_SHARED) 31 | 32 | if (GAINPUT_BUILD_STATIC) 33 | message(STATUS "..Building static libraries (-DGAINPUT_BUILD_STATIC=OFF to disable)") 34 | add_library(gainputstatic STATIC ${sources} ${mmsources}) 35 | set_target_properties(gainputstatic PROPERTIES DEBUG_POSTFIX -d FOLDER gainput) 36 | set(install_libs ${install_libs} gainputstatic) 37 | endif (GAINPUT_BUILD_STATIC) 38 | 39 | if(WIN32) 40 | target_link_libraries(gainput ${XINPUT} ws2_32) 41 | target_link_libraries(gainputstatic ${XINPUT} ws2_32) 42 | add_definitions(-DGAINPUT_LIB_DYNAMIC=1) 43 | elseif(ANDROID) 44 | target_link_libraries(gainputstatic native_app_glue log android) 45 | target_link_libraries(gainput native_app_glue log android) 46 | elseif(APPLE) 47 | find_library(FOUNDATION Foundation) 48 | find_library(IOKIT IOKit) 49 | find_library(GAME_CONTROLLER GameController) 50 | target_link_libraries(gainput ${FOUNDATION} ${IOKIT} ${GAME_CONTROLLER}) 51 | if(IOS) 52 | find_library(UIKIT UIKit) 53 | find_library(COREMOTION CoreMotion) 54 | find_library(QUARTZCORE QuartzCore) 55 | target_link_libraries(gainput ${UIKIT} ${COREMOTION}) 56 | else() 57 | find_library(APPKIT AppKit) 58 | target_link_libraries(gainput ${APPKIT}) 59 | endif() 60 | endif() 61 | 62 | # Library installation directory 63 | if(NOT DEFINED CMAKE_INSTALL_LIBDIR) 64 | set(CMAKE_INSTALL_LIBDIR lib) 65 | endif(NOT DEFINED CMAKE_INSTALL_LIBDIR) 66 | set(libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) 67 | 68 | install( 69 | DIRECTORY "include/gainput" 70 | DESTINATION "include" 71 | FILES_MATCHING PATTERN "*.h" 72 | ) 73 | 74 | install( 75 | TARGETS ${install_libs} 76 | LIBRARY DESTINATION "${libdir}" 77 | ARCHIVE DESTINATION "${libdir}" 78 | RUNTIME DESTINATION "bin" 79 | ) 80 | -------------------------------------------------------------------------------- /lib/include/gainput/GainputDebugRenderer.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTDEBUGRENDERER_H_ 3 | #define GAINPUTDEBUGRENDERER_H_ 4 | 5 | namespace gainput 6 | { 7 | 8 | /// Interface for debug rendering of input device states. 9 | /** 10 | * Coordinates and other measures passed to the interface's functions are in the 11 | * range of 0.0f to 1.0f. 12 | * 13 | * The functions are called as part InputManager::Update(). 14 | */ 15 | class GAINPUT_LIBEXPORT DebugRenderer 16 | { 17 | public: 18 | /// Empty virtual destructor. 19 | virtual ~DebugRenderer() { } 20 | 21 | /// Called to draw a circle with the given radius. 22 | virtual void DrawCircle(float x, float y, float radius) = 0; 23 | 24 | /// Called to draw a line between the two given points. 25 | virtual void DrawLine(float x1, float y1, float x2, float y2) = 0; 26 | 27 | /// Called to draw some text at the given position. 28 | virtual void DrawText(float x, float y, const char* const text) = 0; 29 | }; 30 | 31 | } 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /lib/include/gainput/GainputHelpers.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTHELPERS_H_ 3 | #define GAINPUTHELPERS_H_ 4 | 5 | #include 6 | 7 | namespace gainput 8 | { 9 | 10 | inline void HandleButton(InputDevice& device, InputState& state, InputDeltaState* delta, DeviceButtonId buttonId, bool value) 11 | { 12 | #ifdef GAINPUT_DEBUG 13 | if (value != state.GetBool(buttonId)) 14 | { 15 | GAINPUT_LOG("Button changed: %d, %i\n", buttonId, value); 16 | } 17 | #endif 18 | 19 | if (delta) 20 | { 21 | const bool oldValue = state.GetBool(buttonId); 22 | if (value != oldValue) 23 | { 24 | delta->AddChange(device.GetDeviceId(), buttonId, oldValue, value); 25 | } 26 | } 27 | 28 | state.Set(buttonId, value); 29 | } 30 | 31 | inline void HandleAxis(InputDevice& device, InputState& state, InputDeltaState* delta, DeviceButtonId buttonId, float value) 32 | { 33 | const float deadZone = device.GetDeadZone(buttonId); 34 | if (deadZone > 0.0f) 35 | { 36 | const float absValue = Abs(value); 37 | const float sign = value < 0.0f ? -1.0f : 1.0f; 38 | if (absValue < deadZone) 39 | { 40 | value = 0.0f; 41 | } 42 | else 43 | { 44 | value -= sign*deadZone; 45 | value *= 1.0f / (1.0f - deadZone); 46 | } 47 | } 48 | #ifdef GAINPUT_DEBUG 49 | if (value != state.GetFloat(buttonId)) 50 | { 51 | GAINPUT_LOG("Axis changed: %d, %f\n", buttonId, value); 52 | } 53 | #endif 54 | 55 | if (delta) 56 | { 57 | const float oldValue = state.GetFloat(buttonId); 58 | if (value != oldValue) 59 | { 60 | delta->AddChange(device.GetDeviceId(), buttonId, oldValue, value); 61 | } 62 | } 63 | 64 | state.Set(buttonId, value); 65 | } 66 | 67 | } 68 | 69 | #endif 70 | 71 | 72 | -------------------------------------------------------------------------------- /lib/include/gainput/GainputInputDeltaState.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDELTASTATE_H_ 3 | #define GAINPUTINPUTDELTASTATE_H_ 4 | 5 | namespace gainput 6 | { 7 | 8 | /// Stores a list of input state changes. 9 | class GAINPUT_LIBEXPORT InputDeltaState 10 | { 11 | public: 12 | InputDeltaState(Allocator& allocator); 13 | 14 | /// Add a state change for a bool-type button. 15 | /** 16 | * \param device The input device the change occurred on. 17 | * \param deviceButton The input button that was changed. 18 | * \param oldValue The old button state. 19 | * \param newValue The new button state. 20 | */ 21 | void AddChange(DeviceId device, DeviceButtonId deviceButton, bool oldValue, bool newValue); 22 | /// Add a state change for a float-type button. 23 | /** 24 | * \param device The input device the change occurred on. 25 | * \param deviceButton The input button that was changed. 26 | * \param oldValue The old button state. 27 | * \param newValue The new button state. 28 | */ 29 | void AddChange(DeviceId device, DeviceButtonId deviceButton, float oldValue, float newValue); 30 | 31 | /// Clear list of state changes. 32 | void Clear(); 33 | 34 | /// Notifies all input listeners of the previously recorded state changes. 35 | /** 36 | * \param listeners A list of input listeners to notify. 37 | */ 38 | void NotifyListeners(Array& listeners) const; 39 | 40 | private: 41 | struct Change 42 | { 43 | DeviceId device; 44 | DeviceButtonId deviceButton; 45 | ButtonType type; 46 | union 47 | { 48 | bool b; 49 | float f; 50 | } oldValue, newValue; 51 | }; 52 | 53 | Array changes_; 54 | }; 55 | 56 | } 57 | 58 | #endif 59 | 60 | -------------------------------------------------------------------------------- /lib/include/gainput/GainputInputDeviceBuiltIn.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEBUILTIN_H_ 3 | #define GAINPUTINPUTDEVICEBUILTIN_H_ 4 | 5 | namespace gainput 6 | { 7 | 8 | /// All valid device buttons for InputDeviceBuiltIn. 9 | enum BuiltInButton 10 | { 11 | BuiltInButtonAccelerationX, 12 | BuiltInButtonAccelerationY, 13 | BuiltInButtonAccelerationZ, 14 | BuiltInButtonGravityX, 15 | BuiltInButtonGravityY, 16 | BuiltInButtonGravityZ, 17 | BuiltInButtonGyroscopeX, 18 | BuiltInButtonGyroscopeY, 19 | BuiltInButtonGyroscopeZ, 20 | BuiltInButtonMagneticFieldX, 21 | BuiltInButtonMagneticFieldY, 22 | BuiltInButtonMagneticFieldZ, 23 | BuiltInButtonCount_ 24 | }; 25 | 26 | class InputDeviceBuiltInImpl; 27 | 28 | /// An input device for inputs that are directly built into the executing device (for example, sensors in a phone). 29 | class GAINPUT_LIBEXPORT InputDeviceBuiltIn : public InputDevice 30 | { 31 | public: 32 | /// Initializes the device. 33 | /** 34 | * Instantiate the device using InputManager::CreateDevice(). 35 | * 36 | * \param manager The input manager this device is managed by. 37 | * \param device The ID of this device. 38 | */ 39 | InputDeviceBuiltIn(InputManager& manager, DeviceId device, unsigned index, DeviceVariant variant); 40 | /// Shuts down the device. 41 | ~InputDeviceBuiltIn(); 42 | 43 | /// Returns DT_BUILTIN. 44 | DeviceType GetType() const { return DT_BUILTIN; } 45 | DeviceVariant GetVariant() const; 46 | const char* GetTypeName() const { return "builtin"; } 47 | bool IsValidButtonId(DeviceButtonId deviceButton) const; 48 | 49 | size_t GetAnyButtonDown(DeviceButtonSpec* outButtons, size_t maxButtonCount) const; 50 | 51 | size_t GetButtonName(DeviceButtonId deviceButton, char* buffer, size_t bufferLength) const; 52 | ButtonType GetButtonType(DeviceButtonId deviceButton) const; 53 | DeviceButtonId GetButtonByName(const char* name) const; 54 | 55 | protected: 56 | void InternalUpdate(InputDeltaState* delta); 57 | 58 | DeviceState InternalGetState() const; 59 | 60 | private: 61 | InputDeviceBuiltInImpl* impl_; 62 | 63 | }; 64 | 65 | } 66 | 67 | #endif 68 | 69 | -------------------------------------------------------------------------------- /lib/include/gainput/GainputInputDeviceMouse.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEMOUSE_H_ 3 | #define GAINPUTINPUTDEVICEMOUSE_H_ 4 | 5 | namespace gainput 6 | { 7 | 8 | /// All valid device buttons for InputDeviceMouse. 9 | enum MouseButton 10 | { 11 | MouseButton0 = 0, 12 | MouseButtonLeft = MouseButton0, 13 | MouseButton1, 14 | MouseButtonMiddle = MouseButton1, 15 | MouseButton2, 16 | MouseButtonRight = MouseButton2, 17 | MouseButton3, 18 | MouseButtonWheelUp = MouseButton3, 19 | MouseButton4, 20 | MouseButtonWheelDown = MouseButton4, 21 | MouseButton5, 22 | MouseButton6, 23 | MouseButton7, 24 | MouseButton8, 25 | MouseButton9, 26 | MouseButton10, 27 | MouseButton11, 28 | MouseButton12, 29 | MouseButton13, 30 | MouseButton14, 31 | MouseButton15, 32 | MouseButton16, 33 | MouseButton17, 34 | MouseButton18, 35 | MouseButton19, 36 | MouseButton20, 37 | MouseButtonMax = MouseButton20, 38 | MouseButtonCount, 39 | MouseAxisX = MouseButtonCount, 40 | MouseAxisY, 41 | MouseButtonCount_, 42 | MouseAxisCount = MouseButtonCount_ - MouseAxisX 43 | }; 44 | 45 | 46 | 47 | class InputDeviceMouseImpl; 48 | 49 | /// A mouse input device. 50 | /** 51 | * This input device provides support for standard mouse devices. The valid device buttons are defined 52 | * in the ::MouseButton enum. 53 | * 54 | * This device is implemented on Linux and Windows. 55 | * 56 | * The raw variants (InputDevice::DV_RAW) of this device do not offer normalized absolute axis values. 57 | * That means that the values of MouseAxisX and MouseAxisY don't have defined mininum or maximum 58 | * values. Therefore only the delta (InputMap::GetFloatDelta()) should be used with raw mouse devices. 59 | */ 60 | class GAINPUT_LIBEXPORT InputDeviceMouse : public InputDevice 61 | { 62 | public: 63 | /// Initializes the device. 64 | /** 65 | * Instantiate the device using InputManager::CreateDevice(). 66 | * 67 | * \param manager The input manager this device is managed by. 68 | * \param device The ID of this device. 69 | */ 70 | InputDeviceMouse(InputManager& manager, DeviceId device, unsigned index, DeviceVariant variant); 71 | /// Shuts down the device. 72 | ~InputDeviceMouse(); 73 | 74 | /// Returns DT_MOUSE. 75 | DeviceType GetType() const { return DT_MOUSE; } 76 | DeviceVariant GetVariant() const; 77 | const char* GetTypeName() const { return "mouse"; } 78 | bool IsValidButtonId(DeviceButtonId deviceButton) const { return deviceButton < MouseButtonCount_; } 79 | 80 | size_t GetAnyButtonDown(DeviceButtonSpec* outButtons, size_t maxButtonCount) const; 81 | 82 | size_t GetButtonName(DeviceButtonId deviceButton, char* buffer, size_t bufferLength) const; 83 | ButtonType GetButtonType(DeviceButtonId deviceButton) const; 84 | DeviceButtonId GetButtonByName(const char* name) const; 85 | 86 | /// Returns the platform-specific implementation of this device (internal use only). 87 | InputDeviceMouseImpl* GetPimpl() { return impl_; } 88 | 89 | protected: 90 | void InternalUpdate(InputDeltaState* delta); 91 | DeviceState InternalGetState() const; 92 | 93 | private: 94 | InputDeviceMouseImpl* impl_; 95 | 96 | }; 97 | 98 | } 99 | 100 | #endif 101 | 102 | -------------------------------------------------------------------------------- /lib/include/gainput/GainputInputDeviceTouch.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICETOUCH_H_ 3 | #define GAINPUTINPUTDEVICETOUCH_H_ 4 | 5 | namespace gainput 6 | { 7 | 8 | /// All valid device inputs for InputDeviceTouch. 9 | enum TouchButton 10 | { 11 | Touch0Down, 12 | Touch0X, 13 | Touch0Y, 14 | Touch0Pressure, 15 | Touch1Down, 16 | Touch1X, 17 | Touch1Y, 18 | Touch1Pressure, 19 | Touch2Down, 20 | Touch2X, 21 | Touch2Y, 22 | Touch2Pressure, 23 | Touch3Down, 24 | Touch3X, 25 | Touch3Y, 26 | Touch3Pressure, 27 | Touch4Down, 28 | Touch4X, 29 | Touch4Y, 30 | Touch4Pressure, 31 | Touch5Down, 32 | Touch5X, 33 | Touch5Y, 34 | Touch5Pressure, 35 | Touch6Down, 36 | Touch6X, 37 | Touch6Y, 38 | Touch6Pressure, 39 | Touch7Down, 40 | Touch7X, 41 | Touch7Y, 42 | Touch7Pressure, 43 | TouchCount_ 44 | }; 45 | 46 | 47 | 48 | class InputDeviceTouchImpl; 49 | 50 | /// A touch input device. 51 | /** 52 | * This input device provides support for touch screen/surface devices. The valid device buttons are defined 53 | * in the ::TouchButton enum. For each touch point, there is a boolean input (Touch*Down) showing if the 54 | * touch point is active, two float inputs (Touch*X, Touch*Y) showing the touch point's position, and a 55 | * float input (Touch*Pressure) showing the touch's pressure. 56 | * 57 | * Not all touch points must be numbered consecutively, i.e. point #2 may be down even though #0 and #1 are not. 58 | * 59 | * The number of simultaneously possible touch points is implementaion-dependent. 60 | * 61 | * This device is implemented on Android NDK. 62 | */ 63 | class GAINPUT_LIBEXPORT InputDeviceTouch : public InputDevice 64 | { 65 | public: 66 | /// Initializes the device. 67 | /** 68 | * Instantiate the device using InputManager::CreateDevice(). 69 | * 70 | * \param manager The input manager this device is managed by. 71 | * \param device The ID of this device. 72 | */ 73 | InputDeviceTouch(InputManager& manager, DeviceId device, unsigned index, DeviceVariant variant); 74 | /// Shuts down the device. 75 | ~InputDeviceTouch(); 76 | 77 | /// Returns DT_TOUCH. 78 | DeviceType GetType() const { return DT_TOUCH; } 79 | DeviceVariant GetVariant() const; 80 | const char* GetTypeName() const { return "touch"; } 81 | bool IsValidButtonId(DeviceButtonId deviceButton) const; 82 | 83 | size_t GetAnyButtonDown(DeviceButtonSpec* outButtons, size_t maxButtonCount) const; 84 | 85 | size_t GetButtonName(DeviceButtonId deviceButton, char* buffer, size_t bufferLength) const; 86 | ButtonType GetButtonType(DeviceButtonId deviceButton) const; 87 | DeviceButtonId GetButtonByName(const char* name) const; 88 | 89 | InputState* GetNextInputState(); 90 | 91 | /// Returns the platform-specific implementation of this device. 92 | InputDeviceTouchImpl* GetPimpl() { return impl_; } 93 | 94 | protected: 95 | void InternalUpdate(InputDeltaState* delta); 96 | 97 | DeviceState InternalGetState() const; 98 | 99 | private: 100 | InputDeviceTouchImpl* impl_; 101 | 102 | }; 103 | 104 | } 105 | 106 | #endif 107 | 108 | -------------------------------------------------------------------------------- /lib/include/gainput/GainputInputListener.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTLISTENER_H_ 3 | #define GAINPUTINPUTLISTENER_H_ 4 | 5 | namespace gainput 6 | { 7 | 8 | /// Listener interface that allows to receive notifications when device button states change. 9 | class GAINPUT_LIBEXPORT InputListener 10 | { 11 | public: 12 | virtual ~InputListener() { } 13 | 14 | /// Called when a bool-type button state changes. 15 | /** 16 | * \param device The input device's ID the state change occurred on. 17 | * \param deviceButton The ID of the device button that changed. 18 | * \param oldValue Previous state of the button. 19 | * \param newValue New state of the button. 20 | * \return true if the button may be processed by listeners with a lower priority, false otherwise. 21 | */ 22 | virtual bool OnDeviceButtonBool(DeviceId device, DeviceButtonId deviceButton, bool oldValue, bool newValue) { GAINPUT_UNUSED(device); GAINPUT_UNUSED(deviceButton); GAINPUT_UNUSED(oldValue); GAINPUT_UNUSED(newValue); return true; } 23 | 24 | /// Called when a float-type button state changes. 25 | /** 26 | * \param device The input device's ID the state change occurred on. 27 | * \param deviceButton The ID of the device button that changed. 28 | * \param oldValue Previous state of the button. 29 | * \param newValue New state of the button. 30 | * \return true if the button may be processed by listeners with a lower priority, false otherwise. 31 | */ 32 | virtual bool OnDeviceButtonFloat(DeviceId device, DeviceButtonId deviceButton, float oldValue, float newValue) { GAINPUT_UNUSED(device); GAINPUT_UNUSED(deviceButton); GAINPUT_UNUSED(oldValue); GAINPUT_UNUSED(newValue); return true; } 33 | 34 | /// Returns the priority which influences the order in which listeners are called by InputManager. 35 | /** 36 | * \sa InputManager::ReorderListeners() 37 | */ 38 | virtual int GetPriority() const { return 0; } 39 | }; 40 | 41 | 42 | /// Listener interface that allows to receive notifications when user button states change. 43 | class GAINPUT_LIBEXPORT MappedInputListener 44 | { 45 | public: 46 | virtual ~MappedInputListener() { } 47 | 48 | /// Called when a bool-type button state changes. 49 | /** 50 | * \param userButton The user button's ID. 51 | * \param oldValue Previous state of the button. 52 | * \param newValue New state of the button. 53 | * \return true if the button may be processed by listeners with a lower priority, false otherwise. 54 | */ 55 | virtual bool OnUserButtonBool(UserButtonId userButton, bool oldValue, bool newValue) { GAINPUT_UNUSED(userButton); GAINPUT_UNUSED(oldValue); GAINPUT_UNUSED(newValue); return true; } 56 | 57 | /// Called when a float-type button state changes. 58 | /** 59 | * \param userButton The user button's ID. 60 | * \param oldValue Previous state of the button. 61 | * \param newValue New state of the button. 62 | * \return true if the button may be processed by listeners with a lower priority, false otherwise. 63 | */ 64 | virtual bool OnUserButtonFloat(UserButtonId userButton, float oldValue, float newValue) { GAINPUT_UNUSED(userButton); GAINPUT_UNUSED(oldValue); GAINPUT_UNUSED(newValue); return true; } 65 | 66 | /// Returns the priority which influences the order in which listeners are called by InputMap. 67 | /** 68 | * \sa InputMap::ReorderListeners() 69 | */ 70 | virtual int GetPriority() const { return 0; } 71 | 72 | }; 73 | 74 | } 75 | 76 | #endif 77 | 78 | -------------------------------------------------------------------------------- /lib/include/gainput/GainputInputState.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTSTATE_H_ 3 | #define GAINPUTINPUTSTATE_H_ 4 | 5 | namespace gainput 6 | { 7 | 8 | /// State of an input device. 9 | class GAINPUT_LIBEXPORT InputState 10 | { 11 | public: 12 | /// Initializes the state. 13 | /** 14 | * \param allocator The allocator to be used for all memory allocations. 15 | * \param buttonCount The maximum number of device buttons. 16 | */ 17 | InputState(Allocator& allocator, unsigned int buttonCount); 18 | /// Unitializes the state. 19 | ~InputState(); 20 | 21 | /// Returns the number of buttons in this state. 22 | /** 23 | * Note that not all buttons may be valid. 24 | * 25 | * \sa InputDevice::IsValidButtonId() 26 | */ 27 | unsigned GetButtonCount() const { return buttonCount_; } 28 | 29 | /// Returns the bool state of the given device button. 30 | bool GetBool(DeviceButtonId buttonId) const { return buttons_[buttonId].b; } 31 | /// Sets the bool state of the given device button. 32 | void Set(DeviceButtonId buttonId, bool value) { buttons_[buttonId].b = value; } 33 | /// Returns the float state of the given device button. 34 | float GetFloat(DeviceButtonId buttonId) const { return buttons_[buttonId].f; } 35 | /// Sets the float state of the given device button. 36 | void Set(DeviceButtonId buttonId, float value) { buttons_[buttonId].f = value; } 37 | 38 | /// Sets the states of all buttons in this input state to the states of all buttons in the given input state. 39 | InputState& operator=(const InputState& other); 40 | 41 | private: 42 | Allocator& allocator_; 43 | unsigned int buttonCount_; 44 | 45 | struct Button 46 | { 47 | union 48 | { 49 | bool b; 50 | float f; 51 | }; 52 | }; 53 | 54 | Button* buttons_; 55 | }; 56 | 57 | } 58 | 59 | #endif 60 | 61 | -------------------------------------------------------------------------------- /lib/include/gainput/GainputIos.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTIOS_H_ 3 | #define GAINPUTIOS_H_ 4 | 5 | #import 6 | 7 | namespace gainput 8 | { 9 | class InputManager; 10 | } 11 | 12 | /// [IOS ONLY] UIKit view that captures touch inputs. 13 | /** 14 | * In order to enable touch input on iOS devices (i.e. make the InputDeviceTouch work), 15 | * an instance of this view has to be attached as a subview to the view of your application. 16 | * Note that, for touches to work in portrait and landscape mode, the subview has to be 17 | * rotated correctly with its parent. 18 | */ 19 | @interface GainputView : UIView 20 | 21 | - (id)initWithFrame:(CGRect)frame inputManager:(gainput::InputManager&)inputManager; 22 | 23 | @end 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /lib/include/gainput/GainputLog.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUT_LOG_H_ 3 | #define GAINPUT_LOG_H_ 4 | 5 | #include 6 | 7 | #if defined(GAINPUT_PLATFORM_LINUX) 8 | 9 | #if defined(GAINPUT_DEBUG) || defined(GAINPUT_DEV) 10 | #include 11 | #define GAINPUT_LOG(...) printf(__VA_ARGS__); 12 | #endif 13 | 14 | #elif defined(GAINPUT_PLATFORM_WIN) 15 | 16 | #if defined(GAINPUT_DEBUG) || defined(GAINPUT_DEV) 17 | #include 18 | #include 19 | #define GAINPUT_LOG(...) { char buf[1024]; sprintf(buf, __VA_ARGS__); OutputDebugStringA(buf); } 20 | #endif 21 | 22 | #elif defined(GAINPUT_PLATFORM_ANDROID) 23 | 24 | #if defined(GAINPUT_DEBUG) || defined(GAINPUT_DEV) 25 | #include 26 | #define GAINPUT_LOG(...) ((void)__android_log_print(ANDROID_LOG_INFO, "gainput", __VA_ARGS__)) 27 | #endif 28 | 29 | #elif defined(GAINPUT_PLATFORM_IOS) || defined(GAINPUT_PLATFORM_MAC) || defined(GAINPUT_PLATFORM_TVOS) 30 | #include 31 | #define GAINPUT_LOG(...) printf(__VA_ARGS__); 32 | #endif 33 | 34 | #ifndef GAINPUT_LOG 35 | #define GAINPUT_LOG(...) 36 | #endif 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /lib/include/gainput/GainputMapFilters.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTMAPFILTERS_H_ 3 | #define GAINPUTMAPFILTERS_H_ 4 | 5 | namespace gainput 6 | { 7 | 8 | /// Inverts the given input value in the range [-1.0f, 1.0f]. 9 | GAINPUT_LIBEXPORT float InvertSymmetricInput(float const value, void*); 10 | 11 | /// Inverts the given input value in the range [0.0f, 1.0f]. 12 | GAINPUT_LIBEXPORT float InvertInput(float const value, void*); 13 | 14 | } 15 | 16 | #endif 17 | 18 | -------------------------------------------------------------------------------- /lib/include/gainput/gestures/GainputButtonStickGesture.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTBUTTONSTICKGESTURE_H_ 3 | #define GAINPUTBUTTONSTICKGESTURE_H_ 4 | 5 | #ifdef GAINPUT_ENABLE_BUTTON_STICK_GESTURE 6 | 7 | namespace gainput 8 | { 9 | 10 | /// Buttons provided by the ButtonStickGesture. 11 | enum ButtonStickAction 12 | { 13 | ButtonStickAxis 14 | }; 15 | 16 | 17 | class GAINPUT_LIBEXPORT ButtonStickGesture : public InputGesture 18 | { 19 | public: 20 | /// Initializes the gesture. 21 | ButtonStickGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant variant); 22 | /// Uninitializes the gesture. 23 | ~ButtonStickGesture(); 24 | 25 | /// Sets up the gesture for operation with the given axes and buttons. 26 | void Initialize(DeviceId negativeAxisDevice, DeviceButtonId negativeAxis, 27 | DeviceId positiveAxisDevice, DeviceButtonId positiveAxis); 28 | 29 | bool IsValidButtonId(DeviceButtonId deviceButton) const { return deviceButton == ButtonStickAxis; } 30 | 31 | ButtonType GetButtonType(DeviceButtonId deviceButton) const { GAINPUT_UNUSED(deviceButton); GAINPUT_ASSERT(IsValidButtonId(deviceButton)); return BT_FLOAT; } 32 | 33 | protected: 34 | void InternalUpdate(InputDeltaState* delta); 35 | 36 | private: 37 | DeviceButtonSpec negativeAxis_; 38 | DeviceButtonSpec positiveAxis_; 39 | 40 | }; 41 | 42 | } 43 | 44 | #endif 45 | 46 | #endif 47 | 48 | -------------------------------------------------------------------------------- /lib/include/gainput/gestures/GainputDoubleClickGesture.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTDOUBLECLICKGESTURE_H_ 3 | #define GAINPUTDOUBLECLICKGESTURE_H_ 4 | 5 | #ifdef GAINPUT_ENABLE_DOUBLE_CLICK_GESTURE 6 | 7 | namespace gainput 8 | { 9 | 10 | /// Buttons provided by the DoubleClickGesture. 11 | enum DoubleClickAction 12 | { 13 | DoubleClickTriggered ///< The button triggered by double-clicking. 14 | }; 15 | 16 | /// A double-click gesture. 17 | /** 18 | * This gesture implements the classic double-click functionality. Its only device button ::DoubleClickTriggered is 19 | * true for one frame after the specified button has been active for a specified number of times in a given 20 | * time frame. It's also possible to disallow the pointer from travelling too far between and during clicks. 21 | * 22 | * After instantiating the gesture like any other input device, call one of the Initialize() functions to properly 23 | * set it up. 24 | * 25 | * In order for this gesture to be available, Gainput must be built with \c GAINPUT_ENABLE_ALL_GESTURES or 26 | * \c GAINPUT_ENABLE_DOUBLE_CLICK_GESTURE defined. 27 | * 28 | * \sa Initialize 29 | * \sa SetClicksTargetCount 30 | * \sa InputManager::CreateDevice 31 | */ 32 | class GAINPUT_LIBEXPORT DoubleClickGesture : public InputGesture 33 | { 34 | public: 35 | /// Initializes the gesture. 36 | DoubleClickGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant variant); 37 | /// Uninitializes the gesture. 38 | ~DoubleClickGesture(); 39 | 40 | /// Sets up the gesture for operation without position checking. 41 | /** 42 | * \param actionButtonDevice ID of the input device containing the action button. 43 | * \param actionButton ID of the device button to be used as the action button. 44 | * \param timeSpan Allowed time between clicks in milliseconds. 45 | */ 46 | void Initialize(DeviceId actionButtonDevice, DeviceButtonId actionButton, uint64_t timeSpan = 300); 47 | /// Sets up the gesture for operation with position checking, i.e. the user may not move the mouse too far between clicks. 48 | /** 49 | * \param actionButtonDevice ID of the input device containing the action button. 50 | * \param actionButton ID of the device button to be used as the action button. 51 | * \param xAxisDevice ID of the input device containing the X coordinate of the pointer. 52 | * \param xAxis ID of the device button/axis to be used for the X coordinate of the pointer. 53 | * \param xTolerance The amount the pointer may travel in the X coordinate to still be valid. 54 | * \param yAxisDevice ID of the input device containing the Y coordinate of the pointer. 55 | * \param yAxis ID of the device button/axis to be used for the Y coordinate of the pointer. 56 | * \param yTolerance The amount the pointer may travel in the Y coordinate to still be valid. 57 | * \param timeSpan Allowed time between clicks in milliseconds. 58 | */ 59 | void Initialize(DeviceId actionButtonDevice, DeviceButtonId actionButton, 60 | DeviceId xAxisDevice, DeviceButtonId xAxis, float xTolerance, 61 | DeviceId yAxisDevice, DeviceButtonId yAxis, float yTolerance, 62 | uint64_t timeSpan = 300); 63 | 64 | /// Sets the number of clicks to trigger an action. 65 | /** 66 | * \param count The number of clicks that will trigger this gesture; the default is 2, i.e. double-click. 67 | */ 68 | void SetClicksTargetCount(unsigned count) { clicksTargetCount_ = count; } 69 | 70 | bool IsValidButtonId(DeviceButtonId deviceButton) const { return deviceButton == DoubleClickTriggered; } 71 | 72 | ButtonType GetButtonType(DeviceButtonId deviceButton) const { GAINPUT_UNUSED(deviceButton); GAINPUT_ASSERT(IsValidButtonId(deviceButton)); return BT_BOOL; } 73 | 74 | protected: 75 | void InternalUpdate(InputDeltaState* delta); 76 | 77 | private: 78 | DeviceButtonSpec actionButton_; 79 | DeviceButtonSpec xAxis_; 80 | float xTolerance_; 81 | DeviceButtonSpec yAxis_; 82 | float yTolerance_; 83 | 84 | uint64_t timeSpan_; 85 | uint64_t firstClickTime_; 86 | 87 | float firstClickX_; 88 | float firstClickY_; 89 | 90 | unsigned clicksRegistered_; 91 | unsigned clicksTargetCount_; 92 | }; 93 | 94 | } 95 | 96 | #endif 97 | 98 | #endif 99 | 100 | -------------------------------------------------------------------------------- /lib/include/gainput/gestures/GainputGestures.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTGESTURES_H_ 3 | #define GAINPUTGESTURES_H_ 4 | 5 | #ifdef GAINPUT_ENABLE_ALL_GESTURES 6 | #define GAINPUT_ENABLE_BUTTON_STICK_GESTURE 7 | #define GAINPUT_ENABLE_DOUBLE_CLICK_GESTURE 8 | #define GAINPUT_ENABLE_HOLD_GESTURE 9 | #define GAINPUT_ENABLE_PINCH_GESTURE 10 | #define GAINPUT_ENABLE_ROTATE_GESTURE 11 | #define GAINPUT_ENABLE_SIMULTANEOUSLY_DOWN_GESTURE 12 | #define GAINPUT_ENABLE_TAP_GESTURE 13 | #endif 14 | 15 | 16 | namespace gainput 17 | { 18 | 19 | /// Base class for all input gestures. 20 | /** 21 | * Input gestures are a way to process basic input data into more complex input data. For example, 22 | * multiple buttons may be interpreted over time to form a new button. A very simple gesture would the 23 | * ubiquitous double-click. 24 | * 25 | * Mainly for consistency and convenience reasons, all gestures should derive from this class though it's not 26 | * strictly necessary (deriving from InputDevice would suffice). 27 | * 28 | * Input gestures are basically just input devices that don't get their data from some hardware device 29 | * but from other input devices instead. Therefore gestures must also be created by calling 30 | * InputManager::CreateDevice() or InputManager::CreateAndGetDevice(). Most gestures require further 31 | * initialization which is done by calling one of their \c Initialize() member functions. After that, 32 | * they should be good to go and their buttons can be used like any other input device button, i.e. 33 | * they can be mapped to some user button. 34 | * 35 | * Gestures can be excluded from compilation if they are not required. In order to include all gestures 36 | * \c GAINPUT_ENABLE_ALL_GESTURES should be defined in \c gainput.h . This define must be present when 37 | * the library is built, otherwise the actual functionality won't be present. Similarly, there is one 38 | * define for each gesture. The names of these are documented in the descriptions of the 39 | * individual gesture classes. If no such define is defined, no gesture will be included. 40 | */ 41 | class GAINPUT_LIBEXPORT InputGesture : public InputDevice 42 | { 43 | public: 44 | /// Returns DT_GESTURE. 45 | DeviceType GetType() const { return DT_GESTURE; } 46 | const char* GetTypeName() const { return "gesture"; } 47 | bool IsLateUpdate() const { return true; } 48 | 49 | protected: 50 | /// Gesture base constructor. 51 | InputGesture(InputManager& manager, DeviceId device, unsigned index) : InputDevice(manager, device, index == InputDevice::AutoIndex ? manager.GetDeviceCountByType(DT_GESTURE) : 0) { } 52 | 53 | DeviceState InternalGetState() const { return DS_OK; } 54 | 55 | }; 56 | 57 | } 58 | 59 | 60 | #include 61 | #include 62 | #include 63 | #include 64 | #include 65 | #include 66 | #include 67 | 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /lib/include/gainput/gestures/GainputHoldGesture.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTHOLDGESTURE_H_ 3 | #define GAINPUTHOLDGESTURE_H_ 4 | 5 | #ifdef GAINPUT_ENABLE_HOLD_GESTURE 6 | 7 | namespace gainput 8 | { 9 | 10 | /// Buttons provided by the HoldGesture. 11 | enum HoldAction 12 | { 13 | HoldTriggered ///< The button that triggers after holding for the given time. 14 | }; 15 | 16 | /// A hold-to-trigger gesture. 17 | /** 18 | * This gesture, mainly meant for touch devices, triggers after the specified button has been down for at least 19 | * the specified amount of time. Its button ::HoldTriggered is then either active for one frame or as long as 20 | * the source button is down. 21 | * 22 | * After instantiating the gesture like any other input device, call one of the Initialize() functions to properly 23 | * set it up. 24 | * 25 | * In order for this gesture to be available, Gainput must be built with \c GAINPUT_ENABLE_ALL_GESTURES or 26 | * \c GAINPUT_ENABLE_HOLD_GESTURE defined. 27 | * 28 | * \sa Initialize 29 | * \sa InputManager::CreateDevice 30 | */ 31 | class GAINPUT_LIBEXPORT HoldGesture : public InputGesture 32 | { 33 | public: 34 | /// Initializes the gesture. 35 | HoldGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant variant); 36 | /// Uninitializes the gesture. 37 | ~HoldGesture(); 38 | 39 | /// Sets up the gesture for operation without position checking. 40 | /** 41 | * \param actionButtonDevice ID of the input device containing the action button. 42 | * \param actionButton ID of the device button to be used as the action button. 43 | * \param oneShot Specifies if the gesture triggers only once after the given time or if it triggers as long as the source button is down. 44 | * \param timeSpan Time in milliseconds the user needs to hold in order to trigger the gesture. 45 | */ 46 | void Initialize(DeviceId actionButtonDevice, DeviceButtonId actionButton, bool oneShot = true, uint64_t timeSpan = 800); 47 | /// Sets up the gesture for operation with position checking, i.e. the user may not move the mouse too far while holding. 48 | /** 49 | * \param actionButtonDevice ID of the input device containing the action button. 50 | * \param actionButton ID of the device button to be used as the action button. 51 | * \param xAxisDevice ID of the input device containing the X coordinate of the pointer. 52 | * \param xAxis ID of the device button/axis to be used for the X coordinate of the pointer. 53 | * \param xTolerance The amount the pointer may travel in the X coordinate to still be valid. 54 | * \param yAxisDevice ID of the input device containing the Y coordinate of the pointer. 55 | * \param yAxis ID of the device button/axis to be used for the Y coordinate of the pointer. 56 | * \param yTolerance The amount the pointer may travel in the Y coordinate to still be valid. 57 | * \param oneShot Specifies if the gesture triggers only once after the given time or if it triggers as long as the source button is down. 58 | * \param timeSpan Time in milliseconds the user needs to hold in order to trigger the gesture. 59 | */ 60 | void Initialize(DeviceId actionButtonDevice, DeviceButtonId actionButton, 61 | DeviceId xAxisDevice, DeviceButtonId xAxis, float xTolerance, 62 | DeviceId yAxisDevice, DeviceButtonId yAxis, float yTolerance, 63 | bool oneShot = true, 64 | uint64_t timeSpan = 800); 65 | 66 | bool IsValidButtonId(DeviceButtonId deviceButton) const { return deviceButton == HoldTriggered; } 67 | 68 | ButtonType GetButtonType(DeviceButtonId deviceButton) const { GAINPUT_UNUSED(deviceButton); GAINPUT_ASSERT(IsValidButtonId(deviceButton)); return BT_BOOL; } 69 | 70 | protected: 71 | void InternalUpdate(InputDeltaState* delta); 72 | 73 | private: 74 | DeviceButtonSpec actionButton_; 75 | DeviceButtonSpec xAxis_; 76 | float xTolerance_; 77 | DeviceButtonSpec yAxis_; 78 | float yTolerance_; 79 | 80 | bool oneShot_; 81 | bool oneShotReset_; 82 | uint64_t timeSpan_; 83 | uint64_t firstDownTime_; 84 | 85 | float firstDownX_; 86 | float firstDownY_; 87 | }; 88 | 89 | } 90 | 91 | #endif 92 | 93 | #endif 94 | 95 | -------------------------------------------------------------------------------- /lib/include/gainput/gestures/GainputPinchGesture.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTPINCHGESTURE_H_ 3 | #define GAINPUTPINCHGESTURE_H_ 4 | 5 | #ifdef GAINPUT_ENABLE_PINCH_GESTURE 6 | 7 | namespace gainput 8 | { 9 | 10 | /// Buttons provided by the PinchGesture. 11 | enum PinchAction 12 | { 13 | PinchTriggered, ///< The button that triggers when both pinch buttons are down. 14 | PinchScale ///< The current pinch scale value if pinching is active. 15 | }; 16 | 17 | /// A multi-touch pinch-to-scale gesture. 18 | /** 19 | * This gesture, mainly meant for multi-touch devices, triggers (::PinchTriggered is down) when both specified 20 | * source buttons are down. It will then determine the distance between the two 2D touch points and report 21 | * any change in distance as a factor of the initial distance using ::PinchScale. 22 | * 23 | * After instantiating the gesture like any other input device, call Initialize() to properly 24 | * set it up. 25 | * 26 | * In order for this gesture to be available, Gainput must be built with \c GAINPUT_ENABLE_ALL_GESTURES or 27 | * \c GAINPUT_ENABLE_PINCH_GESTURE defined. 28 | * 29 | * \sa Initialize 30 | * \sa InputManager::CreateDevice 31 | */ 32 | class GAINPUT_LIBEXPORT PinchGesture : public InputGesture 33 | { 34 | public: 35 | /// Initializes the gesture. 36 | PinchGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant variant); 37 | /// Uninitializes the gesture. 38 | ~PinchGesture(); 39 | 40 | /// Sets up the gesture for operation with the given axes and buttons. 41 | /** 42 | * \param downDevice ID of the input device containing the first touch button. 43 | * \param downButton ID of the device button to be used as the first touch button. 44 | * \param xAxisDevice ID of the input device containing the X coordinate of the first touch point. 45 | * \param xAxis ID of the device button/axis to be used for the X coordinate of the first touch point. 46 | * \param yAxisDevice ID of the input device containing the Y coordinate of the first touch point. 47 | * \param yAxis ID of the device button/axis to be used for the Y coordinate of the first touch point. 48 | * \param down2Device ID of the input device containing the second touch button. 49 | * \param downButton2 ID of the device button to be used as the second touch button. 50 | * \param xAxis2Device ID of the input device containing the X coordinate of the second touch point. 51 | * \param xAxis2 ID of the device button/axis to be used for the X coordinate of the second touch point. 52 | * \param yAxis2Device ID of the input device containing the Y coordinate of the second touch point. 53 | * \param yAxis2 ID of the device button/axis to be used for the Y coordinate of the second touch point. 54 | */ 55 | void Initialize(DeviceId downDevice, DeviceButtonId downButton, 56 | DeviceId xAxisDevice, DeviceButtonId xAxis, 57 | DeviceId yAxisDevice, DeviceButtonId yAxis, 58 | DeviceId down2Device, DeviceButtonId downButton2, 59 | DeviceId xAxis2Device, DeviceButtonId xAxis2, 60 | DeviceId yAxis2Device, DeviceButtonId yAxis2); 61 | 62 | bool IsValidButtonId(DeviceButtonId deviceButton) const { return deviceButton == PinchTriggered || deviceButton == PinchScale; } 63 | 64 | ButtonType GetButtonType(DeviceButtonId deviceButton) const { GAINPUT_ASSERT(IsValidButtonId(deviceButton)); return deviceButton == PinchTriggered ? BT_BOOL : BT_FLOAT; } 65 | 66 | protected: 67 | void InternalUpdate(InputDeltaState* delta); 68 | 69 | private: 70 | DeviceButtonSpec downButton_; 71 | DeviceButtonSpec xAxis_; 72 | DeviceButtonSpec yAxis_; 73 | DeviceButtonSpec downButton2_; 74 | DeviceButtonSpec xAxis2_; 75 | DeviceButtonSpec yAxis2_; 76 | 77 | bool pinching_; 78 | float initialDistance_; 79 | }; 80 | 81 | } 82 | 83 | #endif 84 | 85 | #endif 86 | 87 | -------------------------------------------------------------------------------- /lib/include/gainput/gestures/GainputRotateGesture.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTROTATEGESTURE_H_ 3 | #define GAINPUTROTATEGESTURE_H_ 4 | 5 | #ifdef GAINPUT_ENABLE_ROTATE_GESTURE 6 | 7 | namespace gainput 8 | { 9 | 10 | /// Buttons provided by the RotateGesture. 11 | enum RotateAction 12 | { 13 | RotateTriggered, ///< The button that triggers when both rotate buttons are down. 14 | RotateAngle ///< The current rotation angle in radians if rotation is triggered (::RotateTriggered). 15 | }; 16 | 17 | /// A multi-touch rotate gesture. 18 | /** 19 | * This gesture, mainly meant for multi-touch devices, triggers (::RotateTriggered is down) when both specified 20 | * source buttons are down. It then determines the angle between the two specified 2D touch points and reports any 21 | * change in angle using ::RotateAngle. The initial angle between the two points is defined as no rotation. 22 | * 23 | * After instantiating the gesture like any other input device, call Initialize() to properly 24 | * set it up. 25 | * 26 | * In order for this gesture to be available, Gainput must be built with \c GAINPUT_ENABLE_ALL_GESTURES or 27 | * \c GAINPUT_ENABLE_ROTATE_GESTURE defined. 28 | * 29 | * \sa Initialize 30 | * \sa InputManager::CreateDevice 31 | */ 32 | class GAINPUT_LIBEXPORT RotateGesture : public InputGesture 33 | { 34 | public: 35 | /// Initializes the gesture. 36 | RotateGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant variant); 37 | /// Uninitializes the gesture. 38 | ~RotateGesture(); 39 | 40 | /// Sets up the gesture for operation with the given axes and buttons. 41 | /** 42 | * \param downDevice ID of the input device containing the first touch button. 43 | * \param downButton ID of the device button to be used as the first touch button. 44 | * \param xAxisDevice ID of the input device containing the X coordinate of the first touch point. 45 | * \param xAxis ID of the device button/axis to be used for the X coordinate of the first touch point. 46 | * \param yAxisDevice ID of the input device containing the Y coordinate of the first touch point. 47 | * \param yAxis ID of the device button/axis to be used for the Y coordinate of the first touch point. 48 | * \param down2Device ID of the input device containing the second touch button. 49 | * \param downButton2 ID of the device button to be used as the second touch button. 50 | * \param xAxis2Device ID of the input device containing the X coordinate of the second touch point. 51 | * \param xAxis2 ID of the device button/axis to be used for the X coordinate of the second touch point. 52 | * \param yAxis2Device ID of the input device containing the Y coordinate of the second touch point. 53 | * \param yAxis2 ID of the device button/axis to be used for the Y coordinate of the second touch point. 54 | */ 55 | void Initialize(DeviceId downDevice, DeviceButtonId downButton, 56 | DeviceId xAxisDevice, DeviceButtonId xAxis, 57 | DeviceId yAxisDevice, DeviceButtonId yAxis, 58 | DeviceId down2Device, DeviceButtonId downButton2, 59 | DeviceId xAxis2Device, DeviceButtonId xAxis2, 60 | DeviceId yAxis2Device, DeviceButtonId yAxis2); 61 | 62 | bool IsValidButtonId(DeviceButtonId deviceButton) const { return deviceButton == RotateTriggered || deviceButton == RotateAngle; } 63 | 64 | ButtonType GetButtonType(DeviceButtonId deviceButton) const { GAINPUT_ASSERT(IsValidButtonId(deviceButton)); return deviceButton == RotateTriggered ? BT_BOOL : BT_FLOAT; } 65 | 66 | protected: 67 | void InternalUpdate(InputDeltaState* delta); 68 | 69 | private: 70 | DeviceButtonSpec downButton_; 71 | DeviceButtonSpec xAxis_; 72 | DeviceButtonSpec yAxis_; 73 | DeviceButtonSpec downButton2_; 74 | DeviceButtonSpec xAxis2_; 75 | DeviceButtonSpec yAxis2_; 76 | 77 | bool rotating_; 78 | float initialAngle_; 79 | 80 | }; 81 | 82 | } 83 | 84 | #endif 85 | 86 | #endif 87 | 88 | -------------------------------------------------------------------------------- /lib/include/gainput/gestures/GainputSimultaneouslyDownGesture.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTSIMULTANEOUSLYDOWNGESTURE_H_ 3 | #define GAINPUTSIMULTANEOUSLYDOWNGESTURE_H_ 4 | 5 | #ifdef GAINPUT_ENABLE_SIMULTANEOUSLY_DOWN_GESTURE 6 | 7 | namespace gainput 8 | { 9 | 10 | /// Buttons provided by the SimultaneouslyDownGesture. 11 | enum SimultaneouslyDownAction 12 | { 13 | SimultaneouslyDownTriggered ///< The button triggered by double-clicking. 14 | }; 15 | 16 | /// A gesture that tracks if a number of buttons is down simultaneously. 17 | /** 18 | * This gesture can be used to detect if multiple buttons are down at the same time. Its only 19 | * device button ::SimultaneouslyDownTriggered is true while all buttons provided through AddButton() 20 | * are down. 21 | * 22 | * After instantiating the gesture like any other input device, call AddButton() as often as necessary 23 | * to properly set it up. 24 | * 25 | * In order for this gesture to be available, Gainput must be built with \c GAINPUT_ENABLE_ALL_GESTURES or 26 | * \c GAINPUT_ENABLE_SIMULTANEOUSLY_DOWN_GESTURE defined. 27 | * 28 | * \sa AddButton 29 | * \sa InputManager::CreateDevice 30 | */ 31 | class GAINPUT_LIBEXPORT SimultaneouslyDownGesture : public InputGesture 32 | { 33 | public: 34 | /// Initializes the gesture. 35 | SimultaneouslyDownGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant variant); 36 | /// Uninitializes the gesture. 37 | ~SimultaneouslyDownGesture(); 38 | 39 | /// Adds the given button as a button to check. 40 | /** 41 | * \param device ID of the input device containing the button to be checked. 42 | * \param button ID of the device button to be checked. 43 | */ 44 | void AddButton(DeviceId device, DeviceButtonId button); 45 | 46 | /// Removes all buttons previously registered through AddButton(). 47 | void ClearButtons(); 48 | 49 | bool IsValidButtonId(DeviceButtonId deviceButton) const { return deviceButton == SimultaneouslyDownTriggered; } 50 | 51 | ButtonType GetButtonType(DeviceButtonId deviceButton) const { GAINPUT_UNUSED(deviceButton); GAINPUT_ASSERT(IsValidButtonId(deviceButton)); return BT_BOOL; } 52 | 53 | protected: 54 | void InternalUpdate(InputDeltaState* delta); 55 | 56 | private: 57 | Array buttons_; 58 | 59 | }; 60 | 61 | } 62 | 63 | #endif 64 | 65 | #endif 66 | 67 | -------------------------------------------------------------------------------- /lib/include/gainput/gestures/GainputTapGesture.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTTAPGESTURE_H_ 3 | #define GAINPUTTAPGESTURE_H_ 4 | 5 | #ifdef GAINPUT_ENABLE_TAP_GESTURE 6 | 7 | namespace gainput 8 | { 9 | 10 | /// Buttons provided by the TapGesture. 11 | enum TapAction 12 | { 13 | TapTriggered ///< The button that is triggered by tapping. 14 | }; 15 | 16 | /// A tap-to-trigger gesture. 17 | /** 18 | * This gesture, mainly meant for touch devices, triggers after the specified button has been down and released 19 | * during the specified time frame. If the button is down for a longer time, no action is triggered. 20 | * 21 | * After instantiating the gesture like any other input device, call Initialize() to properly 22 | * set it up. 23 | * 24 | * In order for this gesture to be available, Gainput must be built with \c GAINPUT_ENABLE_ALL_GESTURES or 25 | * \c GAINPUT_ENABLE_TAP_GESTURE defined. 26 | * 27 | * \sa Initialize 28 | * \sa InputManager::CreateDevice 29 | */ 30 | class GAINPUT_LIBEXPORT TapGesture : public InputGesture 31 | { 32 | public: 33 | /// Initializes the gesture. 34 | TapGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant variant); 35 | /// Uninitializes the gesture. 36 | ~TapGesture(); 37 | 38 | /// Sets up the gesture. 39 | /** 40 | * \param actionButtonDevice ID of the input device containing the action button. 41 | * \param actionButton ID of the device button to be used as the action button. 42 | * \param timeSpan Time in milliseconds the user may hold at most. 43 | */ 44 | void Initialize(DeviceId actionButtonDevice, DeviceButtonId actionButton, uint64_t timeSpan = 500); 45 | 46 | bool IsValidButtonId(DeviceButtonId deviceButton) const { return deviceButton == TapTriggered; } 47 | 48 | ButtonType GetButtonType(DeviceButtonId deviceButton) const { GAINPUT_UNUSED(deviceButton); GAINPUT_ASSERT(IsValidButtonId(deviceButton)); return BT_BOOL; } 49 | 50 | protected: 51 | void InternalUpdate(InputDeltaState* delta); 52 | 53 | private: 54 | DeviceButtonSpec actionButton_; 55 | 56 | uint64_t timeSpan_; 57 | uint64_t firstDownTime_; 58 | 59 | }; 60 | 61 | } 62 | 63 | #endif 64 | 65 | #endif 66 | 67 | -------------------------------------------------------------------------------- /lib/include/gainput/recorder/GainputInputPlayer.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTPLAYER_H_ 3 | #define GAINPUTINPUTPLAYER_H_ 4 | 5 | #ifdef GAINPUT_ENABLE_RECORDER 6 | 7 | namespace gainput 8 | { 9 | 10 | /// Plays back a previously recorded sequence of device state changes. 11 | /** 12 | * In order for input recording to be available, Gainput must have been built with 13 | * \c GAINPUT_ENABLE_RECORDER defined. 14 | */ 15 | class GAINPUT_LIBEXPORT InputPlayer : public DeviceStateModifier 16 | { 17 | public: 18 | /// Initializes the player. 19 | /** 20 | * \param manager The manager to receive the device state changes. 21 | * \param recording The recording to play, may be 0. 22 | */ 23 | InputPlayer(InputManager& manager, InputRecording* recording = 0); 24 | /// Destructs the player. 25 | ~InputPlayer(); 26 | 27 | /// Updates the player, called internally from InputManager::Update(). 28 | void Update(InputDeltaState* delta); 29 | 30 | /// Starts the playback. 31 | /** 32 | * A recording must have been provided before doing this, either through the 33 | * constructor or SetRecording(). 34 | */ 35 | void Start(); 36 | /// Stops the Playback. 37 | void Stop(); 38 | /// Returns if the player is currently playing. 39 | bool IsPlaying() const { return isPlaying_; } 40 | 41 | /// Sets the recording to play. 42 | void SetRecording(InputRecording* recording); 43 | /// Returns the currently set recording. 44 | InputRecording* GetRecording() { return recording_; } 45 | /// Returns the currently set recording. 46 | const InputRecording* GetRecording() const { return recording_; } 47 | 48 | private: 49 | InputManager& manager_; 50 | 51 | bool isPlaying_; 52 | InputRecording* recording_; 53 | uint64_t startTime_; 54 | 55 | Array devicesToReset_; 56 | 57 | ModifierId playingModifierId_; 58 | }; 59 | 60 | } 61 | 62 | #endif 63 | 64 | #endif 65 | 66 | -------------------------------------------------------------------------------- /lib/include/gainput/recorder/GainputInputRecorder.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTRECORDER_H_ 3 | #define GAINPUTINPUTRECORDER_H_ 4 | 5 | #ifdef GAINPUT_ENABLE_RECORDER 6 | 7 | namespace gainput 8 | { 9 | 10 | /// Records a sequence of button state changes. 11 | /** 12 | * In order for input recording to be available, Gainput must have been built with 13 | * \c GAINPUT_ENABLE_RECORDER defined. 14 | */ 15 | class GAINPUT_LIBEXPORT InputRecorder 16 | { 17 | public: 18 | /// Initializes the recorder. 19 | /** 20 | * \param manager The InputManager to receive button state changes from. 21 | */ 22 | InputRecorder(InputManager& manager); 23 | /// Destructs the recorder. 24 | ~InputRecorder(); 25 | 26 | /// Starts recording. 27 | /** 28 | * Also clears the InputRecording that is being recorded to so that it's not possible 29 | * to resume recording after stopping to record. 30 | */ 31 | void Start(); 32 | /// Stops recording. 33 | void Stop(); 34 | /// Returns if the recorder is currently recording. 35 | bool IsRecording() const { return isRecording_; } 36 | 37 | /// Adds a device to record the button state changes of. 38 | /** 39 | * If no device is set, all devices are recorded. 40 | * \param device The ID of the device to record. 41 | */ 42 | void AddDeviceToRecord(DeviceId device) { recordedDevices_[device] = true; } 43 | /// Returns if the given device should be recorded. 44 | /** 45 | * \param device The ID of the device to check. 46 | */ 47 | bool IsDeviceToRecord(DeviceId device) { return recordedDevices_.empty() || recordedDevices_.count(device) > 0; } 48 | 49 | /// Returns the recording that is being recorded to, may be 0. 50 | InputRecording* GetRecording() { return recording_; } 51 | /// Returns the recording that is being recorded to, may be 0. 52 | const InputRecording* GetRecording() const { return recording_; } 53 | /// Returns the time the recording was started. 54 | uint64_t GetStartTime() const { return startTime_; } 55 | 56 | private: 57 | InputManager& manager_; 58 | 59 | bool isRecording_; 60 | InputListener* recordingListener_; 61 | ListenerId recordingListenerId_; 62 | InputRecording* recording_; 63 | uint64_t startTime_; 64 | HashMap recordedDevices_; 65 | 66 | }; 67 | 68 | } 69 | 70 | #endif 71 | 72 | #endif 73 | 74 | -------------------------------------------------------------------------------- /lib/java/com/example/gainput/gainput/BasicActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.gainput.gainput; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.view.KeyEvent; 6 | import android.view.MotionEvent; 7 | import android.view.View; 8 | 9 | import java.util.Timer; 10 | import java.util.TimerTask; 11 | 12 | import de.johanneskuhlmann.gainput.Gainput; 13 | 14 | public class BasicActivity extends Activity 15 | { 16 | private Gainput gainputHandler; 17 | private Timer timer; 18 | 19 | public static native void nativeOnCreate(); 20 | public static native void nativeOnUpdate(); 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) 24 | { 25 | super.onCreate(savedInstanceState); 26 | System.loadLibrary("basicsample"); 27 | gainputHandler = new Gainput(getApplicationContext()); 28 | nativeOnCreate(); 29 | 30 | getWindow().getDecorView().findViewById(android.R.id.content).addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 31 | @Override 32 | public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { 33 | gainputHandler.viewWidth = v.getWidth(); 34 | gainputHandler.viewHeight = v.getHeight(); 35 | } 36 | }); 37 | 38 | timer = new Timer(); 39 | TimerTask t = new TimerTask() { 40 | int sec = 0; 41 | @Override 42 | public void run() { 43 | nativeOnUpdate(); 44 | } 45 | }; 46 | timer.scheduleAtFixedRate(t, 500, 33); 47 | } 48 | 49 | @Override 50 | public boolean onKeyDown(int keyCode, KeyEvent event) 51 | { 52 | gainputHandler.handleKeyEvent(event); 53 | return super.onKeyDown(keyCode, event); 54 | } 55 | 56 | @Override 57 | public boolean onTouchEvent(MotionEvent event) 58 | { 59 | if (gainputHandler.handleTouchEvent(event)) 60 | { 61 | return true; 62 | } 63 | return super.onTouchEvent(event); 64 | } 65 | 66 | @Override 67 | public boolean dispatchGenericMotionEvent(MotionEvent event) 68 | { 69 | if (gainputHandler.handleMotionEvent(event)) 70 | { 71 | return true; 72 | } 73 | return super.onGenericMotionEvent(event); 74 | } 75 | 76 | @Override 77 | public boolean dispatchKeyEvent (KeyEvent event) 78 | { 79 | if (gainputHandler.handleKeyEvent(event)) 80 | { 81 | return true; 82 | } 83 | return super.dispatchKeyEvent(event); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /lib/source/gainput/GainputAllocator.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | namespace gainput 7 | { 8 | 9 | DefaultAllocator& 10 | GetDefaultAllocator() 11 | { 12 | static DefaultAllocator da; 13 | return da; 14 | } 15 | 16 | 17 | TrackingAllocator::TrackingAllocator(Allocator& backingAllocator, Allocator& internalAllocator) 18 | : backingAllocator_(backingAllocator), 19 | internalAllocator_(internalAllocator), 20 | allocations_(internalAllocator.New >(internalAllocator)), 21 | allocateCount_(0), 22 | deallocateCount_(0), 23 | allocatedMemory_(0) 24 | { 25 | } 26 | 27 | TrackingAllocator::~TrackingAllocator() 28 | { 29 | internalAllocator_.Delete(allocations_); 30 | } 31 | 32 | void* TrackingAllocator::Allocate(size_t size, size_t align) 33 | { 34 | void* ptr = backingAllocator_.Allocate(size, align); 35 | (*allocations_)[ptr] = size; 36 | ++allocateCount_; 37 | allocatedMemory_ += size; 38 | return ptr; 39 | } 40 | 41 | void TrackingAllocator::Deallocate(void* ptr) 42 | { 43 | HashMap::iterator it = allocations_->find(ptr); 44 | if (it == allocations_->end()) 45 | { 46 | GAINPUT_LOG("Warning: Trying to deallocate unknown memory block: %p\n", ptr); 47 | } 48 | else 49 | { 50 | allocatedMemory_ -= it->second; 51 | allocations_->erase(it); 52 | } 53 | ++deallocateCount_; 54 | backingAllocator_.Deallocate(ptr); 55 | } 56 | 57 | } 58 | 59 | -------------------------------------------------------------------------------- /lib/source/gainput/GainputHelpersEvdev.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTHELPERSEVDEV_H_ 3 | #define GAINPUTHELPERSEVDEV_H_ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | namespace gainput 13 | { 14 | namespace 15 | { 16 | 17 | static const unsigned EvdevDeviceCount = 10; 18 | static const char* EvdevDeviceIds[EvdevDeviceCount] = 19 | { 20 | "/dev/input/event0", 21 | "/dev/input/event1", 22 | "/dev/input/event2", 23 | "/dev/input/event3", 24 | "/dev/input/event4", 25 | "/dev/input/event5", 26 | "/dev/input/event6", 27 | "/dev/input/event7", 28 | "/dev/input/event8", 29 | "/dev/input/event9", 30 | }; 31 | 32 | typedef long BitType; 33 | 34 | #define GAINPUT_BITCOUNT (sizeof(BitType)*8) 35 | #define GAINPUT_BITS(n) ((n/GAINPUT_BITCOUNT)+1) 36 | 37 | bool IsBitSet(const BitType* bits, unsigned bit) 38 | { 39 | return bool(bits[bit/GAINPUT_BITCOUNT] & (1ul << (bit % GAINPUT_BITCOUNT))); 40 | } 41 | 42 | bool HasEventType(const BitType* bits, unsigned type) 43 | { 44 | return IsBitSet(bits, type); 45 | } 46 | 47 | bool HasEventCode(const BitType* bits, unsigned code) 48 | { 49 | return IsBitSet(bits, code); 50 | } 51 | 52 | 53 | class EvdevDevice 54 | { 55 | public: 56 | EvdevDevice(int fd) : 57 | valid_(false) 58 | { 59 | int rc; 60 | 61 | memset(name_, 0, sizeof(name_)); 62 | rc = ioctl(fd, EVIOCGNAME(sizeof(name_) - 1), name_); 63 | if (rc < 0) 64 | return; 65 | 66 | GAINPUT_LOG("EVDEV Device name: %s\n", name_); 67 | 68 | rc = ioctl(fd, EVIOCGBIT(0, sizeof(bits_)), bits_); 69 | if (rc < 0) 70 | return; 71 | 72 | rc = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keyBits_)), keyBits_); 73 | if (rc < 0) 74 | return; 75 | 76 | valid_ = true; 77 | } 78 | 79 | bool IsValid() const 80 | { 81 | return valid_; 82 | } 83 | 84 | InputDevice::DeviceType GetDeviceType() const 85 | { 86 | if (HasEventType(bits_, EV_REL) 87 | && HasEventType(bits_, EV_KEY) 88 | && HasEventCode(keyBits_, BTN_LEFT)) 89 | { 90 | GAINPUT_LOG("EVDEV Detected as mouse\n"); 91 | return InputDevice::DT_MOUSE; 92 | } 93 | else if (HasEventType(bits_, EV_KEY) 94 | && HasEventCode(keyBits_, KEY_A) 95 | && HasEventCode(keyBits_, KEY_Q)) 96 | { 97 | GAINPUT_LOG("EVDEV Detected as keyboard\n"); 98 | return InputDevice::DT_KEYBOARD; 99 | } 100 | else if (HasEventType(bits_, EV_ABS) 101 | && HasEventType(bits_, EV_KEY) 102 | && (HasEventCode(keyBits_, BTN_GAMEPAD) 103 | || HasEventCode(keyBits_, BTN_JOYSTICK)) 104 | ) 105 | { 106 | GAINPUT_LOG("EVDEV Detected as pad\n"); 107 | return InputDevice::DT_PAD; 108 | } 109 | 110 | GAINPUT_LOG("EVDEV Unknown device type\n"); 111 | return InputDevice::DT_COUNT; 112 | } 113 | 114 | private: 115 | bool valid_; 116 | char name_[255]; 117 | BitType bits_[GAINPUT_BITS(EV_CNT)]; 118 | BitType keyBits_[GAINPUT_BITS(KEY_CNT)]; 119 | }; 120 | 121 | 122 | } 123 | } 124 | 125 | #endif 126 | 127 | -------------------------------------------------------------------------------- /lib/source/gainput/GainputInputDeltaState.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | 6 | namespace gainput 7 | { 8 | 9 | InputDeltaState::InputDeltaState(Allocator& allocator) : 10 | changes_(allocator) 11 | { 12 | } 13 | 14 | void 15 | InputDeltaState::AddChange(DeviceId device, DeviceButtonId deviceButton, bool oldValue, bool newValue) 16 | { 17 | Change change; 18 | change.device = device; 19 | change.deviceButton = deviceButton; 20 | change.type = BT_BOOL; 21 | change.oldValue.b = oldValue; 22 | change.newValue.b = newValue; 23 | changes_.push_back(change); 24 | } 25 | 26 | void 27 | InputDeltaState::AddChange(DeviceId device, DeviceButtonId deviceButton, float oldValue, float newValue) 28 | { 29 | Change change; 30 | change.device = device; 31 | change.deviceButton = deviceButton; 32 | change.type = BT_FLOAT; 33 | change.oldValue.f = oldValue; 34 | change.newValue.f = newValue; 35 | changes_.push_back(change); 36 | } 37 | 38 | void 39 | InputDeltaState::Clear() 40 | { 41 | changes_.clear(); 42 | } 43 | 44 | void 45 | InputDeltaState::NotifyListeners(Array& listeners) const 46 | { 47 | for (Array::const_iterator it = changes_.begin(); 48 | it != changes_.end(); 49 | ++it) 50 | { 51 | const Change& change = *it; 52 | for (Array::iterator it2 = listeners.begin(); 53 | it2 != listeners.end(); 54 | ++it2) 55 | { 56 | if (change.type == BT_BOOL) 57 | { 58 | if (!(*it2)->OnDeviceButtonBool(change.device, change.deviceButton, change.oldValue.b, change.newValue.b)) 59 | { 60 | break; 61 | } 62 | } 63 | else if (change.type == BT_FLOAT) 64 | { 65 | if(!(*it2)->OnDeviceButtonFloat(change.device, change.deviceButton, change.oldValue.f, change.newValue.f)) 66 | { 67 | break; 68 | } 69 | } 70 | } 71 | } 72 | } 73 | 74 | } 75 | 76 | -------------------------------------------------------------------------------- /lib/source/gainput/GainputInputDevice.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | namespace gainput 5 | { 6 | 7 | 8 | InputDevice::InputDevice(InputManager& manager, DeviceId device, unsigned index) : 9 | manager_(manager), 10 | deviceId_(device), 11 | index_(index), 12 | deadZones_(0), 13 | debugRenderingEnabled_(false) 14 | #if defined(GAINPUT_DEV) || defined(GAINPUT_ENABLE_RECORDER) 15 | , synced_(false) 16 | #endif 17 | { 18 | } 19 | 20 | InputDevice::~InputDevice() 21 | { 22 | manager_.GetAllocator().Deallocate(deadZones_); 23 | } 24 | 25 | void 26 | InputDevice::Update(InputDeltaState* delta) 27 | { 28 | *previousState_ = *state_; 29 | #if defined(GAINPUT_DEV) 30 | if (synced_) 31 | { 32 | return; 33 | } 34 | #endif 35 | InternalUpdate(delta); 36 | } 37 | 38 | InputDevice::DeviceState 39 | InputDevice::GetState() const 40 | { 41 | #if defined(GAINPUT_DEV) 42 | if (synced_) 43 | { 44 | return DS_OK; 45 | } 46 | #endif 47 | return InternalGetState(); 48 | } 49 | 50 | float InputDevice::GetDeadZone(DeviceButtonId buttonId) const 51 | { 52 | if (!deadZones_ 53 | || !IsValidButtonId(buttonId)) 54 | { 55 | return 0.0f; 56 | } 57 | GAINPUT_ASSERT(buttonId < state_->GetButtonCount()); 58 | return deadZones_[buttonId]; 59 | } 60 | 61 | void InputDevice::SetDeadZone(DeviceButtonId buttonId, float value) 62 | { 63 | if (!deadZones_) 64 | { 65 | const size_t size = sizeof(float) * state_->GetButtonCount(); 66 | deadZones_ = reinterpret_cast(manager_.GetAllocator().Allocate(size)); 67 | memset(deadZones_, 0, size); 68 | } 69 | GAINPUT_ASSERT(buttonId < state_->GetButtonCount()); 70 | deadZones_[buttonId] = value; 71 | } 72 | 73 | void 74 | InputDevice::SetDebugRenderingEnabled(bool enabled) 75 | { 76 | debugRenderingEnabled_ = enabled; 77 | } 78 | 79 | size_t 80 | InputDevice::CheckAllButtonsDown(DeviceButtonSpec* outButtons, size_t maxButtonCount, unsigned start, unsigned end) const 81 | { 82 | size_t buttonsFound = 0; 83 | for (unsigned i = start; i < end && buttonsFound < maxButtonCount; ++i) 84 | { 85 | DeviceButtonId id(i); 86 | if (IsValidButtonId(id) && GetBool(id)) 87 | { 88 | outButtons[buttonsFound].deviceId = deviceId_; 89 | outButtons[buttonsFound].buttonId = id; 90 | ++buttonsFound; 91 | } 92 | } 93 | return buttonsFound; 94 | } 95 | 96 | } 97 | 98 | -------------------------------------------------------------------------------- /lib/source/gainput/GainputInputState.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | 5 | namespace gainput 6 | { 7 | 8 | InputState::InputState(Allocator& allocator, unsigned int buttonCount) : 9 | allocator_(allocator), 10 | buttonCount_(buttonCount) 11 | { 12 | const size_t size = sizeof(Button) * buttonCount_; 13 | buttons_ = static_cast(allocator_.Allocate(size)); 14 | GAINPUT_ASSERT(buttons_); 15 | memset(buttons_, 0, size); 16 | } 17 | 18 | InputState::~InputState() 19 | { 20 | allocator_.Deallocate(buttons_); 21 | } 22 | 23 | InputState& 24 | InputState::operator=(const InputState& other) 25 | { 26 | const size_t size = sizeof(Button) * buttonCount_; 27 | memcpy(buttons_, other.buttons_, size); 28 | return *this; 29 | } 30 | 31 | } 32 | 33 | -------------------------------------------------------------------------------- /lib/source/gainput/GainputMac.mm: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #ifdef GAINPUT_PLATFORM_MAC 5 | 6 | #import 7 | 8 | namespace gainput 9 | { 10 | 11 | bool MacIsApplicationKey() 12 | { 13 | return [[NSApplication sharedApplication] keyWindow ] != nil; 14 | } 15 | 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /lib/source/gainput/GainputMapFilters.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | 6 | namespace gainput 7 | { 8 | 9 | float InvertSymmetricInput(float const value, void*) 10 | { 11 | return -value; 12 | } 13 | 14 | float InvertInput(float const value, void*) 15 | { 16 | return 1.0f - value; 17 | } 18 | 19 | } 20 | 21 | -------------------------------------------------------------------------------- /lib/source/gainput/GainputWindows.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTWINDOWS_H_ 3 | #define GAINPUTWINDOWS_H_ 4 | 5 | #define WIN32_LEAN_AND_MEAN 6 | 7 | #ifndef NOMINMAX 8 | #define NOMINMAX 9 | #endif 10 | 11 | #include 12 | #include 13 | #ifdef DrawText 14 | #undef DrawText 15 | #endif 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /lib/source/gainput/builtin/GainputInputDeviceBuiltIn.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include "GainputInputDeviceBuiltInImpl.h" 6 | #include 7 | #include 8 | #include 9 | 10 | #if defined(GAINPUT_PLATFORM_ANDROID) 11 | #include "GainputInputDeviceBuiltInAndroid.h" 12 | #elif defined(GAINPUT_PLATFORM_IOS) 13 | #include "GainputInputDeviceBuiltInIos.h" 14 | #endif 15 | 16 | #include "GainputInputDeviceBuiltInNull.h" 17 | 18 | namespace gainput 19 | { 20 | 21 | namespace 22 | { 23 | struct DeviceButtonInfo 24 | { 25 | ButtonType type; 26 | const char* name; 27 | }; 28 | 29 | DeviceButtonInfo deviceButtonInfos[] = 30 | { 31 | { BT_FLOAT, "builtin_acceleration_x" }, 32 | { BT_FLOAT, "builtin_acceleration_y" }, 33 | { BT_FLOAT, "builtin_acceleration_z" }, 34 | { BT_FLOAT, "builtin_gravity_x" }, 35 | { BT_FLOAT, "builtin_gravity_y" }, 36 | { BT_FLOAT, "builtin_gravity_z" }, 37 | { BT_FLOAT, "builtin_gyroscope_x" }, 38 | { BT_FLOAT, "builtin_gyroscope_y" }, 39 | { BT_FLOAT, "builtin_gyroscope_z" }, 40 | { BT_FLOAT, "builtin_magneticfield_x" }, 41 | { BT_FLOAT, "builtin_magneticfield_y" }, 42 | { BT_FLOAT, "builtin_magneticfield_z" }, 43 | }; 44 | 45 | const unsigned BuiltInButtonCount = BuiltInButtonCount_; 46 | 47 | } 48 | 49 | 50 | InputDeviceBuiltIn::InputDeviceBuiltIn(InputManager& manager, DeviceId device, unsigned index, DeviceVariant /*variant*/) : 51 | InputDevice(manager, device, index == InputDevice::AutoIndex ? manager.GetDeviceCountByType(DT_BUILTIN) : 0), 52 | impl_(0) 53 | { 54 | state_ = manager.GetAllocator().New(manager.GetAllocator(), BuiltInButtonCount); 55 | GAINPUT_ASSERT(state_); 56 | previousState_ = manager.GetAllocator().New(manager.GetAllocator(), BuiltInButtonCount); 57 | GAINPUT_ASSERT(previousState_); 58 | 59 | #if defined(GAINPUT_PLATFORM_ANDROID) 60 | impl_ = manager.GetAllocator().New(manager, *this, index_, *state_, *previousState_); 61 | #elif defined(GAINPUT_PLATFORM_IOS) 62 | impl_ = manager.GetAllocator().New(manager, *this, index_, *state_, *previousState_); 63 | #endif 64 | 65 | if (!impl_) 66 | { 67 | impl_ = manager.GetAllocator().New(manager, *this, index_, *state_, *previousState_); 68 | } 69 | 70 | GAINPUT_ASSERT(impl_); 71 | } 72 | 73 | InputDeviceBuiltIn::~InputDeviceBuiltIn() 74 | { 75 | manager_.GetAllocator().Delete(state_); 76 | manager_.GetAllocator().Delete(previousState_); 77 | manager_.GetAllocator().Delete(impl_); 78 | } 79 | 80 | void 81 | InputDeviceBuiltIn::InternalUpdate(InputDeltaState* delta) 82 | { 83 | impl_->Update(delta); 84 | } 85 | 86 | InputDevice::DeviceState 87 | InputDeviceBuiltIn::InternalGetState() const 88 | { 89 | return impl_->GetState(); 90 | } 91 | 92 | InputDevice::DeviceVariant 93 | InputDeviceBuiltIn::GetVariant() const 94 | { 95 | return impl_->GetVariant(); 96 | } 97 | 98 | bool 99 | InputDeviceBuiltIn::IsValidButtonId(DeviceButtonId deviceButton) const 100 | { 101 | return impl_->IsValidButton(deviceButton); 102 | } 103 | 104 | size_t 105 | InputDeviceBuiltIn::GetAnyButtonDown(DeviceButtonSpec* outButtons, size_t maxButtonCount) const 106 | { 107 | GAINPUT_ASSERT(outButtons); 108 | GAINPUT_ASSERT(maxButtonCount > 0); 109 | return CheckAllButtonsDown(outButtons, maxButtonCount, BuiltInButtonAccelerationX, BuiltInButtonCount_); 110 | } 111 | 112 | size_t 113 | InputDeviceBuiltIn::GetButtonName(DeviceButtonId deviceButton, char* buffer, size_t bufferLength) const 114 | { 115 | GAINPUT_ASSERT(IsValidButtonId(deviceButton)); 116 | GAINPUT_ASSERT(buffer); 117 | GAINPUT_ASSERT(bufferLength > 0); 118 | strncpy(buffer, deviceButtonInfos[deviceButton].name, bufferLength); 119 | buffer[bufferLength-1] = 0; 120 | const size_t nameLen = strlen(deviceButtonInfos[deviceButton].name); 121 | return nameLen >= bufferLength ? bufferLength : nameLen+1; 122 | } 123 | 124 | ButtonType 125 | InputDeviceBuiltIn::GetButtonType(DeviceButtonId deviceButton) const 126 | { 127 | return deviceButtonInfos[deviceButton].type; 128 | } 129 | 130 | DeviceButtonId 131 | InputDeviceBuiltIn::GetButtonByName(const char* name) const 132 | { 133 | GAINPUT_ASSERT(name); 134 | for (unsigned i = 0; i < BuiltInButtonCount; ++i) 135 | { 136 | if (strcmp(name, deviceButtonInfos[i].name) == 0) 137 | { 138 | return DeviceButtonId(i); 139 | } 140 | } 141 | return InvalidDeviceButtonId; 142 | } 143 | 144 | } 145 | 146 | -------------------------------------------------------------------------------- /lib/source/gainput/builtin/GainputInputDeviceBuiltInImpl.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEBUILTINIMPL_H_ 3 | #define GAINPUTINPUTDEVICEBUILTINIMPL_H_ 4 | 5 | namespace gainput 6 | { 7 | 8 | class InputDeviceBuiltInImpl 9 | { 10 | public: 11 | virtual ~InputDeviceBuiltInImpl() { } 12 | virtual InputDevice::DeviceVariant GetVariant() const = 0; 13 | virtual InputDevice::DeviceState GetState() const { return InputDevice::DS_OK; } 14 | virtual void Update(InputDeltaState* delta) = 0; 15 | virtual bool IsValidButton(DeviceButtonId deviceButton) const = 0; 16 | }; 17 | 18 | } 19 | 20 | #endif 21 | 22 | -------------------------------------------------------------------------------- /lib/source/gainput/builtin/GainputInputDeviceBuiltInIos.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEBUILTINIOS_H_ 3 | #define GAINPUTINPUTDEVICEBUILTINIOS_H_ 4 | 5 | 6 | namespace gainput 7 | { 8 | 9 | class InputDeviceBuiltInImplIos : public InputDeviceBuiltInImpl 10 | { 11 | public: 12 | InputDeviceBuiltInImplIos(InputManager& manager, InputDevice& device, unsigned index, InputState& state, InputState& previousState); 13 | ~InputDeviceBuiltInImplIos(); 14 | 15 | InputDevice::DeviceVariant GetVariant() const 16 | { 17 | return InputDevice::DV_STANDARD; 18 | } 19 | 20 | void Update(InputDeltaState* delta); 21 | 22 | InputDevice::DeviceState GetState() const 23 | { 24 | return deviceState_; 25 | } 26 | 27 | bool IsValidButton(DeviceButtonId deviceButton) const; 28 | 29 | bool Vibrate(float leftMotor, float rightMotor) 30 | { 31 | return false; 32 | } 33 | 34 | bool pausePressed_; 35 | 36 | private: 37 | InputManager& manager_; 38 | InputDevice& device_; 39 | unsigned index_; 40 | bool padFound_; 41 | InputState& state_; 42 | InputState& previousState_; 43 | InputDevice::DeviceState deviceState_; 44 | 45 | void* motionManager_; 46 | 47 | }; 48 | 49 | } 50 | 51 | #endif 52 | 53 | -------------------------------------------------------------------------------- /lib/source/gainput/builtin/GainputInputDeviceBuiltInIos.mm: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef GAINPUT_PLATFORM_IOS 4 | 5 | #include "GainputInputDeviceBuiltInImpl.h" 6 | #include 7 | #include 8 | #include 9 | 10 | #include "GainputInputDeviceBuiltInIos.h" 11 | 12 | #import 13 | 14 | namespace gainput 15 | { 16 | 17 | InputDeviceBuiltInImplIos::InputDeviceBuiltInImplIos(InputManager& manager, InputDevice& device, unsigned index, InputState& state, InputState& previousState) 18 | : pausePressed_(false), 19 | manager_(manager), 20 | device_(device), 21 | index_(index), 22 | padFound_(false), 23 | state_(state), 24 | previousState_(previousState), 25 | deviceState_(InputDevice::DS_UNAVAILABLE), 26 | motionManager_(0) 27 | { 28 | CMMotionManager* motionManager = [[CMMotionManager alloc] init]; 29 | [motionManager startDeviceMotionUpdates]; 30 | motionManager_ = motionManager; 31 | deviceState_ = InputDevice::DS_OK; 32 | } 33 | 34 | InputDeviceBuiltInImplIos::~InputDeviceBuiltInImplIos() 35 | { 36 | CMMotionManager* motionManager = reinterpret_cast(motionManager_); 37 | [motionManager stopDeviceMotionUpdates]; 38 | [motionManager release]; 39 | } 40 | 41 | void InputDeviceBuiltInImplIos::Update(InputDeltaState* delta) 42 | { 43 | GAINPUT_ASSERT(motionManager_); 44 | @autoreleasepool { 45 | CMMotionManager* motionManager = reinterpret_cast(motionManager_); 46 | CMDeviceMotion* motion = motionManager.deviceMotion; 47 | if (!motion) 48 | { 49 | return; 50 | } 51 | 52 | HandleAxis(device_, state_, delta, BuiltInButtonAccelerationX, motion.userAcceleration.x); 53 | HandleAxis(device_, state_, delta, BuiltInButtonAccelerationY, motion.userAcceleration.y); 54 | HandleAxis(device_, state_, delta, BuiltInButtonAccelerationZ, motion.userAcceleration.z); 55 | 56 | HandleAxis(device_, state_, delta, BuiltInButtonGravityX, motion.gravity.x); 57 | HandleAxis(device_, state_, delta, BuiltInButtonGravityY, motion.gravity.y); 58 | HandleAxis(device_, state_, delta, BuiltInButtonGravityZ, motion.gravity.z); 59 | 60 | const float gyroX = 2.0f * (motion.attitude.quaternion.x * motion.attitude.quaternion.z + motion.attitude.quaternion.w * motion.attitude.quaternion.y); 61 | const float gyroY = 2.0f * (motion.attitude.quaternion.y * motion.attitude.quaternion.z - motion.attitude.quaternion.w * motion.attitude.quaternion.x); 62 | const float gyroZ = 1.0f - 2.0f * (motion.attitude.quaternion.x * motion.attitude.quaternion.x + motion.attitude.quaternion.y * motion.attitude.quaternion.y); 63 | HandleAxis(device_, state_, delta, BuiltInButtonGyroscopeX, gyroX); 64 | HandleAxis(device_, state_, delta, BuiltInButtonGyroscopeY, gyroY); 65 | HandleAxis(device_, state_, delta, BuiltInButtonGyroscopeZ, gyroZ); 66 | 67 | HandleAxis(device_, state_, delta, BuiltInButtonMagneticFieldX, motion.magneticField.field.x); 68 | HandleAxis(device_, state_, delta, BuiltInButtonMagneticFieldY, motion.magneticField.field.y); 69 | HandleAxis(device_, state_, delta, BuiltInButtonMagneticFieldZ, motion.magneticField.field.z); 70 | 71 | } 72 | } 73 | 74 | bool InputDeviceBuiltInImplIos::IsValidButton(DeviceButtonId deviceButton) const 75 | { 76 | return deviceButton >= BuiltInButtonAccelerationX && deviceButton <= BuiltInButtonMagneticFieldZ; 77 | } 78 | 79 | } 80 | 81 | #endif 82 | 83 | -------------------------------------------------------------------------------- /lib/source/gainput/builtin/GainputInputDeviceBuiltInNull.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEBUILTINNULL_H_ 3 | #define GAINPUTINPUTDEVICEBUILTINNULL_H_ 4 | 5 | 6 | namespace gainput 7 | { 8 | 9 | class InputDeviceBuiltInImplNull : public InputDeviceBuiltInImpl 10 | { 11 | public: 12 | InputDeviceBuiltInImplNull(InputManager& /*manager*/, InputDevice& /*device*/, unsigned /*index*/, InputState& /*state*/, InputState& /*previousState*/) 13 | { 14 | } 15 | 16 | InputDevice::DeviceVariant GetVariant() const 17 | { 18 | return InputDevice::DV_NULL; 19 | } 20 | 21 | void Update(InputDeltaState* /*delta*/) 22 | { 23 | } 24 | 25 | InputDevice::DeviceState GetState() const 26 | { 27 | return InputDevice::DS_OK; 28 | } 29 | 30 | bool IsValidButton(DeviceButtonId /*deviceButton*/) const 31 | { 32 | return false; 33 | } 34 | }; 35 | 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /lib/source/gainput/dev/GainputDev.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTDEV_H_ 3 | #define GAINPUTDEV_H_ 4 | 5 | #ifdef GAINPUT_DEV 6 | 7 | #include "GainputDevProtocol.h" 8 | 9 | namespace gainput 10 | { 11 | 12 | void DevInit(InputManager* inputManager); 13 | void DevShutdown(const InputManager* inputManager); 14 | void DevUpdate(InputDeltaState* delta); 15 | void DevNewMap(InputMap* inputMap); 16 | void DevNewUserButton(InputMap* inputMap, UserButtonId userButton, DeviceId device, DeviceButtonId deviceButton); 17 | void DevRemoveUserButton(InputMap* inputMap, UserButtonId userButton); 18 | void DevRemoveMap(InputMap* inputMap); 19 | void DevNewDevice(InputDevice* device); 20 | void DevConnect(InputManager* inputManager, const char* ip, unsigned port); 21 | void DevStartDeviceSync(DeviceId deviceId); 22 | 23 | } 24 | 25 | #define GAINPUT_DEV_INIT(inputManager) DevInit(inputManager) 26 | #define GAINPUT_DEV_SHUTDOWN(inputManager) DevShutdown(inputManager) 27 | #define GAINPUT_DEV_UPDATE(delta) DevUpdate(delta) 28 | #define GAINPUT_DEV_NEW_MAP(inputMap) DevNewMap(inputMap) 29 | #define GAINPUT_DEV_NEW_USER_BUTTON(inputMap, userButton, device, deviceButton) DevNewUserButton(inputMap, userButton, device, deviceButton) 30 | #define GAINPUT_DEV_REMOVE_USER_BUTTON(inputMap, userButton) DevRemoveUserButton(inputMap, userButton) 31 | #define GAINPUT_DEV_REMOVE_MAP(inputMap) DevRemoveMap(inputMap) 32 | #define GAINPUT_DEV_NEW_DEVICE(device) DevNewDevice(device) 33 | #define GAINPUT_DEV_CONNECT(inputManager, ip, port) DevConnect(inputManager, ip, port) 34 | #define GAINPUT_DEV_START_SYNC(deviceId) DevStartDeviceSync(deviceId) 35 | 36 | #else 37 | 38 | #define GAINPUT_DEV_INIT(inputManager) 39 | #define GAINPUT_DEV_SHUTDOWN(inputManager) 40 | #define GAINPUT_DEV_UPDATE(delta) 41 | #define GAINPUT_DEV_NEW_MAP(inputMap) 42 | #define GAINPUT_DEV_NEW_USER_BUTTON(inputMap, userButton, device, deviceButton) 43 | #define GAINPUT_DEV_REMOVE_USER_BUTTON(inputMap, userButton) 44 | #define GAINPUT_DEV_REMOVE_MAP(inputMap) 45 | #define GAINPUT_DEV_NEW_DEVICE(device) 46 | #define GAINPUT_DEV_CONNECT(inputManager, ip, port) 47 | #define GAINPUT_DEV_START_SYNC(device) 48 | 49 | #endif 50 | 51 | #endif 52 | 53 | -------------------------------------------------------------------------------- /lib/source/gainput/dev/GainputDevProtocol.h: -------------------------------------------------------------------------------- 1 | #ifndef GAINPUTDEVPROTOCOL_H_ 2 | #define GAINPUTDEVPROTOCOL_H_ 3 | 4 | namespace gainput 5 | { 6 | 7 | enum DevCmd 8 | { 9 | DevCmdHello, 10 | DevCmdDevice, 11 | DevCmdDeviceButton, 12 | DevCmdMap, 13 | DevCmdRemoveMap, 14 | DevCmdUserButton, 15 | DevCmdRemoveUserButton, 16 | DevCmdPing, 17 | DevCmdUserButtonChanged, 18 | DevCmdGetAllInfos, 19 | DevCmdStartDeviceSync, 20 | DevCmdSetDeviceButton, 21 | }; 22 | 23 | const static unsigned DevProtocolVersion = 0x3; 24 | 25 | } 26 | 27 | #endif 28 | 29 | -------------------------------------------------------------------------------- /lib/source/gainput/dev/GainputMemoryStream.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #if defined(GAINPUT_DEV) || defined(GAINPUT_ENABLE_RECORDER) 4 | #include "GainputMemoryStream.h" 5 | 6 | namespace gainput { 7 | 8 | MemoryStream::MemoryStream(void* data, size_t length, size_t capacity, bool ownership) : 9 | data_(data), 10 | length_(length), 11 | capacity_(capacity), 12 | ownership_(ownership), 13 | position_(0) 14 | { 15 | // empty 16 | } 17 | 18 | MemoryStream::MemoryStream(size_t capacity, Allocator& allocator) : 19 | allocator_(&allocator), 20 | length_(0), 21 | capacity_(capacity), 22 | ownership_(true), 23 | position_(0) 24 | { 25 | data_ = this->allocator_->Allocate(capacity_); 26 | } 27 | 28 | MemoryStream::~MemoryStream() 29 | { 30 | if (ownership_) 31 | { 32 | assert(allocator_); 33 | allocator_->Deallocate(data_); 34 | } 35 | } 36 | 37 | size_t 38 | MemoryStream::Read(void* dest, size_t readLength) 39 | { 40 | assert(position_ + readLength <= length_); 41 | memcpy(dest, (void*)( (uint8_t*)data_ + position_), readLength); 42 | position_ += readLength; 43 | return readLength; 44 | } 45 | 46 | size_t 47 | MemoryStream::Write(const void* src, size_t writeLength) 48 | { 49 | assert(position_ + writeLength <= capacity_); 50 | memcpy((void*)( (uint8_t*)data_ + position_), src, writeLength); 51 | position_ += writeLength; 52 | length_ += writeLength; 53 | return writeLength; 54 | } 55 | 56 | bool 57 | MemoryStream::SeekBegin(int offset) 58 | { 59 | if (offset < 0) 60 | { 61 | return false; 62 | } 63 | position_ = offset; 64 | return true; 65 | } 66 | 67 | bool 68 | MemoryStream::SeekCurrent(int offset) 69 | { 70 | if (offset + position_ > length_) 71 | { 72 | return false; 73 | } 74 | position_ += offset; 75 | return true; 76 | } 77 | 78 | bool 79 | MemoryStream::SeekEnd(int offset) 80 | { 81 | if (offset > 0) 82 | { 83 | return false; 84 | } 85 | position_ = length_ + offset; 86 | return true; 87 | } 88 | 89 | } 90 | #endif 91 | 92 | -------------------------------------------------------------------------------- /lib/source/gainput/dev/GainputMemoryStream.h: -------------------------------------------------------------------------------- 1 | #ifndef GAINPUTMEMORYSTREAM_H_ 2 | #define GAINPUTMEMORYSTREAM_H_ 3 | 4 | #include "GainputStream.h" 5 | 6 | namespace gainput { 7 | 8 | class MemoryStream : public Stream 9 | { 10 | public: 11 | MemoryStream(void* data, size_t length, size_t capacity, bool ownership = false); 12 | MemoryStream(size_t capacity, Allocator& allocator = GetDefaultAllocator()); 13 | ~MemoryStream(); 14 | 15 | size_t Read(void* dest, size_t readLength); 16 | size_t Write(const void* src, size_t writeLength); 17 | 18 | size_t GetSize() const { return length_; } 19 | size_t GetLeft() const { return length_ - position_; } 20 | 21 | bool SeekBegin(int offset); 22 | bool SeekCurrent(int offset); 23 | bool SeekEnd(int offset); 24 | 25 | virtual void Reset() { length_ = 0; position_ = 0; } 26 | 27 | bool IsEof() const 28 | { 29 | return position_ >= length_; 30 | } 31 | 32 | void* GetData() { return data_; } 33 | size_t GetPosition() const { return position_; } 34 | 35 | private: 36 | Allocator* allocator_; 37 | void* data_; 38 | size_t length_; 39 | size_t capacity_; 40 | bool ownership_; 41 | 42 | size_t position_; 43 | 44 | }; 45 | 46 | } 47 | 48 | #endif 49 | 50 | -------------------------------------------------------------------------------- /lib/source/gainput/dev/GainputNetAddress.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef GAINPUT_DEV 4 | #include "GainputNetAddress.h" 5 | 6 | #if defined(GAINPUT_PLATFORM_LINUX) || defined(GAINPUT_PLATFORM_ANDROID) || defined(GAINPUT_PLATFORM_WIN) || defined(GAINPUT_PLATFORM_IOS) || defined(GAINPUT_PLATFORM_MAC) || defined(GAINPUT_PLATFORM_TVOS) 7 | 8 | #if defined(GAINPUT_PLATFORM_LINUX) || defined(GAINPUT_PLATFORM_ANDROID) || defined(GAINPUT_PLATFORM_IOS) || defined(GAINPUT_PLATFORM_MAC) || defined(GAINPUT_PLATFORM_TVOS) 9 | #include 10 | #include 11 | #include 12 | #endif 13 | 14 | namespace gainput { 15 | 16 | NetAddress::NetAddress(const char* ip, unsigned port) 17 | { 18 | #if defined(GAINPUT_PLATFORM_LINUX) || defined(GAINPUT_PLATFORM_ANDROID) || defined(GAINPUT_PLATFORM_IOS) || defined(GAINPUT_PLATFORM_MAC) || defined(GAINPUT_PLATFORM_TVOS) 19 | struct in_addr inp; 20 | if (!inet_aton(ip, &inp)) 21 | { 22 | assert(false); 23 | return; 24 | } 25 | addr.sin_addr.s_addr = inp.s_addr; 26 | #elif defined(GAINPUT_PLATFORM_WIN) 27 | addr.sin_addr.s_addr = inet_addr(ip); 28 | #endif 29 | 30 | addr.sin_family = AF_INET; 31 | addr.sin_port = htons(port); 32 | } 33 | 34 | NetAddress::NetAddress(const struct sockaddr_in& rhs) 35 | { 36 | addr.sin_family = rhs.sin_family; 37 | addr.sin_addr.s_addr = rhs.sin_addr.s_addr; 38 | addr.sin_port = rhs.sin_port; 39 | } 40 | 41 | } 42 | #endif 43 | #endif 44 | 45 | -------------------------------------------------------------------------------- /lib/source/gainput/dev/GainputNetAddress.h: -------------------------------------------------------------------------------- 1 | #ifndef GAINPUTADDRESS_H_ 2 | #define GAINPUTADDRESS_H_ 3 | 4 | #if defined(GAINPUT_PLATFORM_LINUX) || defined(GAINPUT_PLATFORM_ANDROID) || defined(GAINPUT_PLATFORM_IOS) || defined(GAINPUT_PLATFORM_MAC) || defined(GAINPUT_PLATFORM_TVOS) 5 | #include 6 | #include 7 | #include 8 | #elif defined(GAINPUT_PLATFORM_WIN) 9 | #define _WINSOCK_DEPRECATED_NO_WARNINGS 10 | #include 11 | #include 12 | #endif 13 | 14 | namespace gainput { 15 | 16 | class NetAddress 17 | { 18 | public: 19 | NetAddress(const char* ip, unsigned port); 20 | 21 | #if defined(GAINPUT_PLATFORM_LINUX) || defined(GAINPUT_PLATFORM_ANDROID) || defined(GAINPUT_PLATFORM_WIN) || defined(GAINPUT_PLATFORM_IOS) || defined(GAINPUT_PLATFORM_MAC) || defined(GAINPUT_PLATFORM_TVOS) 22 | NetAddress(const struct sockaddr_in& rhs); 23 | 24 | const struct sockaddr_in& GetAddr() const { return addr; } 25 | struct sockaddr_in& GetAddr() { return addr; } 26 | #endif 27 | 28 | NetAddress& operator = (const NetAddress& rhs); 29 | 30 | private: 31 | #if defined(GAINPUT_PLATFORM_LINUX) || defined(GAINPUT_PLATFORM_ANDROID) || defined(GAINPUT_PLATFORM_WIN) || defined(GAINPUT_PLATFORM_IOS) || defined(GAINPUT_PLATFORM_MAC) || defined(GAINPUT_PLATFORM_TVOS) 32 | struct sockaddr_in addr; 33 | #endif 34 | 35 | }; 36 | 37 | 38 | inline 39 | NetAddress& 40 | NetAddress::operator = (const NetAddress& rhs) 41 | { 42 | #if defined(GAINPUT_PLATFORM_LINUX) || defined(GAINPUT_PLATFORM_ANDROID) || defined(GAINPUT_PLATFORM_WIN) || defined(GAINPUT_PLATFORM_IOS) || defined(GAINPUT_PLATFORM_MAC) || defined(GAINPUT_PLATFORM_TVOS) 43 | addr.sin_family = rhs.addr.sin_family; 44 | addr.sin_addr.s_addr = rhs.addr.sin_addr.s_addr; 45 | addr.sin_port = rhs.addr.sin_port; 46 | #endif 47 | return *this; 48 | } 49 | 50 | } 51 | 52 | #endif 53 | 54 | -------------------------------------------------------------------------------- /lib/source/gainput/dev/GainputNetConnection.h: -------------------------------------------------------------------------------- 1 | #ifndef GAINPUTCONNECTION_H_ 2 | #define GAINPUTCONNECTION_H_ 3 | 4 | #include "GainputNetAddress.h" 5 | 6 | namespace gainput { 7 | 8 | class Stream; 9 | 10 | class NetConnection 11 | { 12 | public: 13 | NetConnection(const NetAddress& address, Allocator& allocator = GetDefaultAllocator()); 14 | #if defined(GAINPUT_PLATFORM_LINUX) || defined(GAINPUT_PLATFORM_ANDROID) || defined(GAINPUT_PLATFORM_IOS) || defined(GAINPUT_PLATFORM_MAC) || defined(GAINPUT_PLATFORM_TVOS) 15 | NetConnection(const NetAddress& remoteAddress, int fd, Allocator& allocator = GetDefaultAllocator()); 16 | #elif defined(GAINPUT_PLATFORM_WIN) 17 | NetConnection(const NetAddress& remoteAddress, SOCKET fd, Allocator& allocator = GetDefaultAllocator()); 18 | #endif 19 | ~NetConnection(); 20 | 21 | bool Connect(bool shouldBlock); 22 | void Close(); 23 | bool IsConnected() const; 24 | bool IsReady(bool read, bool write); 25 | 26 | size_t Send(const void* buffer, size_t length); 27 | size_t Send(Stream& stream); 28 | 29 | size_t Receive(void* buffer, size_t length); 30 | size_t Receive(Stream& stream, size_t maxLength); 31 | 32 | private: 33 | Allocator& allocator; 34 | NetAddress address; 35 | 36 | #if defined(GAINPUT_PLATFORM_LINUX) || defined(GAINPUT_PLATFORM_ANDROID) || defined(GAINPUT_PLATFORM_IOS) || defined(GAINPUT_PLATFORM_MAC) || defined(GAINPUT_PLATFORM_TVOS) 37 | int fd; 38 | #elif defined(GAINPUT_PLATFORM_WIN) 39 | SOCKET fd; 40 | #endif 41 | 42 | }; 43 | 44 | } 45 | 46 | #endif 47 | 48 | -------------------------------------------------------------------------------- /lib/source/gainput/dev/GainputNetListener.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef GAINPUT_DEV 4 | #include "GainputNetAddress.h" 5 | #include "GainputNetConnection.h" 6 | #include "GainputNetListener.h" 7 | 8 | #if defined(GAINPUT_PLATFORM_LINUX) || defined(GAINPUT_PLATFORM_ANDROID) || defined(GAINPUT_PLATFORM_IOS) || defined(GAINPUT_PLATFORM_MAC) || defined(GAINPUT_PLATFORM_TVOS) 9 | #include 10 | #include 11 | 12 | namespace gainput { 13 | 14 | NetListener::NetListener(const NetAddress& address, Allocator& allocator) : 15 | address(address), 16 | allocator(allocator), 17 | blocking(true), 18 | fd(-1) 19 | { 20 | 21 | } 22 | 23 | NetListener::~NetListener() 24 | { 25 | Stop(); 26 | } 27 | 28 | bool 29 | NetListener::Start(bool shouldBlock) 30 | { 31 | assert(fd == -1); 32 | 33 | blocking = shouldBlock; 34 | 35 | fd = socket(AF_INET, SOCK_STREAM, 0); 36 | if (fd == -1) 37 | { 38 | return false; 39 | } 40 | 41 | if (!shouldBlock && fcntl(fd, F_SETFL, O_NONBLOCK) == -1) 42 | { 43 | return false; 44 | } 45 | 46 | const int sock_reuse_optval = 1; 47 | setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &sock_reuse_optval, sizeof(sock_reuse_optval)); 48 | 49 | if (bind(fd, (struct sockaddr*)&address.GetAddr(), sizeof(struct sockaddr_in)) == -1) 50 | { 51 | return false; 52 | } 53 | 54 | if (listen(fd, 50) == -1) 55 | { 56 | return false; 57 | } 58 | 59 | return true; 60 | } 61 | 62 | void 63 | NetListener::Stop() 64 | { 65 | if (fd == -1) 66 | { 67 | return; 68 | } 69 | 70 | close(fd); 71 | fd = -1; 72 | } 73 | 74 | NetConnection* 75 | NetListener::Accept() 76 | { 77 | assert(fd != -1); 78 | struct sockaddr_in addr; 79 | socklen_t addr_len = sizeof(struct sockaddr_in); 80 | 81 | int remoteFd = accept(fd, (struct sockaddr*)&addr, &addr_len); 82 | if (remoteFd == -1) 83 | { 84 | return 0; 85 | } 86 | 87 | if (!blocking) 88 | { 89 | fcntl(remoteFd, F_SETFL, O_NONBLOCK); 90 | } 91 | 92 | NetAddress remoteAddress(addr); 93 | NetConnection* connection = allocator.New(remoteAddress, remoteFd, allocator); 94 | 95 | return connection; 96 | } 97 | 98 | } 99 | 100 | #elif defined(GAINPUT_PLATFORM_WIN) 101 | 102 | namespace gainput { 103 | 104 | NetListener::NetListener(const NetAddress& address, Allocator& allocator) : 105 | address(address), 106 | allocator(allocator), 107 | blocking(true), 108 | listenSocket(INVALID_SOCKET) 109 | { 110 | 111 | } 112 | 113 | NetListener::~NetListener() 114 | { 115 | Stop(); 116 | } 117 | 118 | bool 119 | NetListener::Start(bool shouldBlock) 120 | { 121 | assert(listenSocket == INVALID_SOCKET); 122 | listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 123 | if (listenSocket == INVALID_SOCKET) 124 | { 125 | return false; 126 | } 127 | 128 | if (!shouldBlock) 129 | { 130 | u_long NonBlock = 1; 131 | if (ioctlsocket(listenSocket, FIONBIO, &NonBlock) == SOCKET_ERROR) 132 | { 133 | return false; 134 | } 135 | } 136 | 137 | if (bind(listenSocket, (struct sockaddr*)&address.GetAddr(), sizeof(struct sockaddr_in)) == SOCKET_ERROR) 138 | { 139 | closesocket(listenSocket); 140 | return false; 141 | } 142 | 143 | if (listen(listenSocket, SOMAXCONN ) == SOCKET_ERROR) 144 | { 145 | closesocket(listenSocket); 146 | return false; 147 | } 148 | 149 | return true; 150 | } 151 | 152 | void 153 | NetListener::Stop() 154 | { 155 | if (listenSocket == INVALID_SOCKET) 156 | { 157 | return; 158 | } 159 | 160 | closesocket(listenSocket); 161 | listenSocket = INVALID_SOCKET; 162 | } 163 | 164 | NetConnection* 165 | NetListener::Accept() 166 | { 167 | assert(listenSocket != INVALID_SOCKET); 168 | struct sockaddr_in addr; 169 | int addr_len = sizeof(struct sockaddr_in); 170 | SOCKET remoteSocket = accept(listenSocket, (struct sockaddr*)&addr, &addr_len); 171 | if (remoteSocket == INVALID_SOCKET) 172 | { 173 | return 0; 174 | } 175 | NetAddress remoteAddress(addr); 176 | NetConnection* connection = allocator.New(remoteAddress, remoteSocket, allocator); 177 | return connection; 178 | } 179 | 180 | } 181 | 182 | 183 | #endif 184 | #endif 185 | 186 | -------------------------------------------------------------------------------- /lib/source/gainput/dev/GainputNetListener.h: -------------------------------------------------------------------------------- 1 | #ifndef GAINPUTLISTENER_H_ 2 | #define GAINPUTLISTENER_H_ 3 | 4 | #include 5 | #include "GainputNetAddress.h" 6 | 7 | namespace gainput { 8 | 9 | class NetConnection; 10 | 11 | class NetListener 12 | { 13 | public: 14 | NetListener(const NetAddress& address, Allocator& allocator = GetDefaultAllocator()); 15 | ~NetListener(); 16 | 17 | bool Start(bool shouldBlock); 18 | void Stop(); 19 | 20 | NetConnection* Accept(); 21 | 22 | private: 23 | NetAddress address; 24 | Allocator& allocator; 25 | bool blocking; 26 | 27 | #if defined(GAINPUT_PLATFORM_LINUX) || defined(GAINPUT_PLATFORM_ANDROID) || defined(GAINPUT_PLATFORM_IOS) || defined(GAINPUT_PLATFORM_MAC) || defined(GAINPUT_PLATFORM_TVOS) 28 | int fd; 29 | #elif defined(GAINPUT_PLATFORM_WIN) 30 | SOCKET listenSocket; 31 | #endif 32 | 33 | }; 34 | 35 | } 36 | 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /lib/source/gainput/dev/GainputStream.h: -------------------------------------------------------------------------------- 1 | #ifndef GAINPUTSTREAM_H_ 2 | #define GAINPUTSTREAM_H_ 3 | 4 | #if defined(GAINPUT_PLATFORM_LINUX) || defined(GAINPUT_PLATFORM_ANDROID) 5 | #include 6 | #include 7 | #elif defined(GAINPUT_PLATFORM_WIN) 8 | #include 9 | typedef unsigned __int16 uint16_t; 10 | typedef __int16 int16_t; 11 | typedef unsigned __int32 uint32_t; 12 | typedef __int32 int32_t; 13 | #endif 14 | 15 | namespace gainput { 16 | 17 | class Stream 18 | { 19 | public: 20 | virtual ~Stream() { } 21 | 22 | virtual size_t Read(void* dest, size_t length) = 0; 23 | virtual size_t Write(const void* src, size_t length) = 0; 24 | 25 | virtual size_t GetSize() const = 0; 26 | virtual size_t GetLeft() const = 0; 27 | 28 | virtual bool SeekBegin(int offset) = 0; 29 | virtual bool SeekCurrent(int offset) = 0; 30 | virtual bool SeekEnd(int offset) = 0; 31 | 32 | virtual void Reset() = 0; 33 | 34 | virtual bool IsEof() const = 0; 35 | 36 | template size_t Read(T& dest) { return Read(&dest, sizeof(T)); } 37 | template size_t Write(const T& src) { return Write(&src, sizeof(T)); } 38 | 39 | }; 40 | 41 | template<> 42 | inline 43 | size_t 44 | Stream::Read(uint16_t& dest) 45 | { 46 | const size_t result = Read(&dest, sizeof(dest)); 47 | dest = ntohs(dest); 48 | return result; 49 | } 50 | 51 | template<> 52 | inline 53 | size_t 54 | Stream::Read(int16_t& dest) 55 | { 56 | const size_t result = Read(&dest, sizeof(dest)); 57 | dest = ntohs((uint16_t)dest); 58 | return result; 59 | } 60 | 61 | template<> 62 | inline 63 | size_t 64 | Stream::Read(uint32_t& dest) 65 | { 66 | const size_t result = Read(&dest, sizeof(dest)); 67 | dest = ntohl(dest); 68 | return result; 69 | } 70 | 71 | template<> 72 | inline 73 | size_t 74 | Stream::Read(int32_t& dest) 75 | { 76 | const size_t result = Read(&dest, sizeof(dest)); 77 | dest = ntohl((uint32_t)dest); 78 | return result; 79 | } 80 | 81 | template<> 82 | inline 83 | size_t 84 | Stream::Read(float& dest) 85 | { 86 | const size_t result = Read(&dest, sizeof(dest)); 87 | const uint32_t tmpInt = ntohl(*(uint32_t*)&dest); 88 | const float* tmpFloatP = (float*)&tmpInt; 89 | dest = *tmpFloatP; 90 | return result; 91 | } 92 | 93 | 94 | template<> 95 | inline 96 | size_t 97 | Stream::Write(const uint16_t& src) 98 | { 99 | const uint16_t tmp = htons(src); 100 | return Write(&tmp, sizeof(tmp)); 101 | } 102 | 103 | template<> 104 | inline 105 | size_t 106 | Stream::Write(const int16_t& src) 107 | { 108 | const int16_t tmp = htons((uint16_t)src); 109 | return Write(&tmp, sizeof(tmp)); 110 | } 111 | 112 | template<> 113 | inline 114 | size_t 115 | Stream::Write(const uint32_t& src) 116 | { 117 | const uint32_t tmp = htonl(src); 118 | return Write(&tmp, sizeof(tmp)); 119 | } 120 | 121 | template<> 122 | inline 123 | size_t 124 | Stream::Write(const int32_t& src) 125 | { 126 | const int32_t tmp = htonl((uint32_t)src); 127 | return Write(&tmp, sizeof(tmp)); 128 | } 129 | 130 | template<> 131 | inline 132 | size_t 133 | Stream::Write(const float& src) 134 | { 135 | const uint32_t tmpInt = htonl(*(uint32_t*)&src); 136 | const float* tmpFloatP = (float*)&tmpInt; 137 | const float tmp = *tmpFloatP; 138 | return Write(&tmp, sizeof(tmp)); 139 | } 140 | 141 | 142 | } 143 | 144 | #endif 145 | 146 | -------------------------------------------------------------------------------- /lib/source/gainput/gestures/GainputButtonStickGesture.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #ifdef GAINPUT_ENABLE_BUTTON_STICK_GESTURE 6 | #include 7 | #include 8 | 9 | namespace gainput 10 | { 11 | 12 | ButtonStickGesture::ButtonStickGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant /*variant*/) : 13 | InputGesture(manager, device, index) 14 | { 15 | negativeAxis_.buttonId = InvalidDeviceButtonId; 16 | positiveAxis_.buttonId = InvalidDeviceButtonId; 17 | 18 | state_ = manager_.GetAllocator().New(manager.GetAllocator(), 1); 19 | GAINPUT_ASSERT(state_); 20 | previousState_ = manager_.GetAllocator().New(manager.GetAllocator(), 1); 21 | GAINPUT_ASSERT(previousState_); 22 | } 23 | 24 | ButtonStickGesture::~ButtonStickGesture() 25 | { 26 | manager_.GetAllocator().Delete(state_); 27 | manager_.GetAllocator().Delete(previousState_); 28 | } 29 | 30 | void 31 | ButtonStickGesture::Initialize(DeviceId negativeAxisDevice, DeviceButtonId negativeAxis, 32 | DeviceId positiveAxisDevice, DeviceButtonId positiveAxis) 33 | { 34 | negativeAxis_.deviceId = negativeAxisDevice; 35 | negativeAxis_.buttonId = negativeAxis; 36 | positiveAxis_.deviceId = positiveAxisDevice; 37 | positiveAxis_.buttonId = positiveAxis; 38 | } 39 | 40 | void 41 | ButtonStickGesture::InternalUpdate(InputDeltaState* delta) 42 | { 43 | if (negativeAxis_.buttonId == InvalidDeviceButtonId 44 | || positiveAxis_.buttonId == InvalidDeviceButtonId) 45 | { 46 | return; 47 | } 48 | 49 | const InputDevice* negativeDevice = manager_.GetDevice(negativeAxis_.deviceId); 50 | GAINPUT_ASSERT(negativeDevice); 51 | const bool isDown = negativeDevice->GetBool(negativeAxis_.buttonId); 52 | 53 | const InputDevice* positiveDevice = manager_.GetDevice(positiveAxis_.deviceId); 54 | GAINPUT_ASSERT(positiveDevice); 55 | const bool isDown2 = positiveDevice->GetBool(positiveAxis_.buttonId); 56 | 57 | if (isDown && !isDown2) 58 | { 59 | HandleAxis(*this, *state_, delta, ButtonStickAxis, -1.0f); 60 | } 61 | else if (!isDown && isDown2) 62 | { 63 | HandleAxis(*this, *state_, delta, ButtonStickAxis, 1.0f); 64 | } 65 | else 66 | { 67 | HandleAxis(*this, *state_, delta, ButtonStickAxis, 0.0f); 68 | } 69 | } 70 | 71 | } 72 | 73 | #endif 74 | 75 | -------------------------------------------------------------------------------- /lib/source/gainput/gestures/GainputDoubleClickGesture.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #ifdef GAINPUT_ENABLE_DOUBLE_CLICK_GESTURE 6 | #include 7 | #include 8 | 9 | namespace gainput 10 | { 11 | 12 | DoubleClickGesture::DoubleClickGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant /*variant*/) : 13 | InputGesture(manager, device, index), 14 | timeSpan_(1000), 15 | firstClickTime_(0), 16 | clicksRegistered_(0), 17 | clicksTargetCount_(2) 18 | { 19 | actionButton_.buttonId = InvalidDeviceButtonId; 20 | xAxis_.buttonId = InvalidDeviceButtonId; 21 | yAxis_.buttonId = InvalidDeviceButtonId; 22 | 23 | state_ = manager_.GetAllocator().New(manager.GetAllocator(), 1); 24 | GAINPUT_ASSERT(state_); 25 | previousState_ = manager_.GetAllocator().New(manager.GetAllocator(), 1); 26 | GAINPUT_ASSERT(previousState_); 27 | } 28 | 29 | DoubleClickGesture::~DoubleClickGesture() 30 | { 31 | manager_.GetAllocator().Delete(state_); 32 | manager_.GetAllocator().Delete(previousState_); 33 | } 34 | 35 | void 36 | DoubleClickGesture::Initialize(DeviceId actionButtonDevice, DeviceButtonId actionButton, uint64_t timeSpan) 37 | { 38 | actionButton_.deviceId = actionButtonDevice; 39 | actionButton_.buttonId = actionButton; 40 | xAxis_.buttonId = InvalidDeviceButtonId; 41 | yAxis_.buttonId = InvalidDeviceButtonId; 42 | timeSpan_ = timeSpan; 43 | } 44 | 45 | void 46 | DoubleClickGesture::Initialize(DeviceId actionButtonDevice, DeviceButtonId actionButton, 47 | DeviceId xAxisDevice, DeviceButtonId xAxis, float xTolerance, 48 | DeviceId yAxisDevice, DeviceButtonId yAxis, float yTolerance, 49 | uint64_t timeSpan) 50 | { 51 | actionButton_.deviceId = actionButtonDevice; 52 | actionButton_.buttonId = actionButton; 53 | xAxis_.deviceId = xAxisDevice; 54 | xAxis_.buttonId = xAxis; 55 | xTolerance_ = xTolerance; 56 | yAxis_.deviceId = yAxisDevice; 57 | yAxis_.buttonId = yAxis; 58 | yTolerance_ = yTolerance; 59 | timeSpan_ = timeSpan; 60 | } 61 | 62 | void 63 | DoubleClickGesture::InternalUpdate(InputDeltaState* delta) 64 | { 65 | if (actionButton_.buttonId == InvalidDeviceButtonId) 66 | { 67 | return; 68 | } 69 | 70 | const InputDevice* actionDevice = manager_.GetDevice(actionButton_.deviceId); 71 | GAINPUT_ASSERT(actionDevice); 72 | 73 | bool positionValid = false; 74 | float clickX = 0.0f; 75 | float clickY = 0.0f; 76 | if (xAxis_.buttonId != InvalidDeviceButtonId && yAxis_.buttonId != InvalidDeviceButtonId) 77 | { 78 | const InputDevice* xAxisDevice = manager_.GetDevice(xAxis_.deviceId); 79 | GAINPUT_ASSERT(xAxisDevice); 80 | clickX = xAxisDevice->GetFloat(xAxis_.buttonId); 81 | const InputDevice* yAxisDevice = manager_.GetDevice(yAxis_.deviceId); 82 | GAINPUT_ASSERT(yAxisDevice); 83 | clickY = yAxisDevice->GetFloat(yAxis_.buttonId); 84 | positionValid = true; 85 | } 86 | 87 | if (actionDevice->GetBoolPrevious(actionButton_.buttonId) 88 | && !actionDevice->GetBool(actionButton_.buttonId)) 89 | { 90 | if (clicksRegistered_ == 0) 91 | { 92 | firstClickTime_ = manager_.GetTime(); 93 | firstClickX_ = clickX; 94 | firstClickY_ = clickY; 95 | } 96 | ++clicksRegistered_; 97 | } 98 | 99 | if (firstClickTime_ + timeSpan_ < manager_.GetTime()) 100 | { 101 | clicksRegistered_ = 0; 102 | } 103 | 104 | if (positionValid && clicksRegistered_ > 1 105 | && (Abs(clickX - firstClickX_) > xTolerance_ || Abs(clickY - firstClickY_) > yTolerance_)) 106 | { 107 | clicksRegistered_ = 0; 108 | } 109 | 110 | if (clicksRegistered_ >= clicksTargetCount_) 111 | { 112 | clicksRegistered_ = 0; 113 | HandleButton(*this, *state_, delta, DoubleClickTriggered, true); 114 | } 115 | else 116 | { 117 | HandleButton(*this, *state_, delta, DoubleClickTriggered, false); 118 | } 119 | } 120 | 121 | } 122 | 123 | #endif 124 | 125 | -------------------------------------------------------------------------------- /lib/source/gainput/gestures/GainputHoldGesture.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #ifdef GAINPUT_ENABLE_HOLD_GESTURE 6 | #include 7 | #include 8 | 9 | namespace gainput 10 | { 11 | 12 | HoldGesture::HoldGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant /*variant*/) : 13 | InputGesture(manager, device, index), 14 | oneShotReset_(true), 15 | firstDownTime_(0) 16 | { 17 | actionButton_.buttonId = InvalidDeviceButtonId; 18 | xAxis_.buttonId = InvalidDeviceButtonId; 19 | yAxis_.buttonId = InvalidDeviceButtonId; 20 | 21 | state_ = manager_.GetAllocator().New(manager.GetAllocator(), 1); 22 | GAINPUT_ASSERT(state_); 23 | previousState_ = manager_.GetAllocator().New(manager.GetAllocator(), 1); 24 | GAINPUT_ASSERT(previousState_); 25 | } 26 | 27 | HoldGesture::~HoldGesture() 28 | { 29 | manager_.GetAllocator().Delete(state_); 30 | manager_.GetAllocator().Delete(previousState_); 31 | } 32 | 33 | void 34 | HoldGesture::Initialize(DeviceId actionButtonDevice, DeviceButtonId actionButton, bool oneShot, uint64_t timeSpan) 35 | { 36 | actionButton_.deviceId = actionButtonDevice; 37 | actionButton_.buttonId = actionButton; 38 | xAxis_.buttonId = InvalidDeviceButtonId; 39 | yAxis_.buttonId = InvalidDeviceButtonId; 40 | oneShot_ = oneShot; 41 | timeSpan_ = timeSpan; 42 | } 43 | 44 | void 45 | HoldGesture::Initialize(DeviceId actionButtonDevice, DeviceButtonId actionButton, 46 | DeviceId xAxisDevice, DeviceButtonId xAxis, float xTolerance, 47 | DeviceId yAxisDevice, DeviceButtonId yAxis, float yTolerance, 48 | bool oneShot, 49 | uint64_t timeSpan) 50 | { 51 | actionButton_.deviceId = actionButtonDevice; 52 | actionButton_.buttonId = actionButton; 53 | xAxis_.deviceId = xAxisDevice; 54 | xAxis_.buttonId = xAxis; 55 | xTolerance_ = xTolerance; 56 | yAxis_.deviceId = yAxisDevice; 57 | yAxis_.buttonId = yAxis; 58 | yTolerance_ = yTolerance; 59 | oneShot_ = oneShot; 60 | timeSpan_ = timeSpan; 61 | } 62 | 63 | void 64 | HoldGesture::InternalUpdate(InputDeltaState* delta) 65 | { 66 | if (actionButton_.buttonId == InvalidDeviceButtonId) 67 | { 68 | return; 69 | } 70 | 71 | const InputDevice* actionDevice = manager_.GetDevice(actionButton_.deviceId); 72 | GAINPUT_ASSERT(actionDevice); 73 | 74 | bool positionValid = false; 75 | float posX = 0.0f; 76 | float posY = 0.0f; 77 | if (xAxis_.buttonId != InvalidDeviceButtonId && yAxis_.buttonId != InvalidDeviceButtonId) 78 | { 79 | const InputDevice* xAxisDevice = manager_.GetDevice(xAxis_.deviceId); 80 | GAINPUT_ASSERT(xAxisDevice); 81 | posX = xAxisDevice->GetFloat(xAxis_.buttonId); 82 | const InputDevice* yAxisDevice = manager_.GetDevice(yAxis_.deviceId); 83 | GAINPUT_ASSERT(yAxisDevice); 84 | posY = yAxisDevice->GetFloat(yAxis_.buttonId); 85 | positionValid = true; 86 | } 87 | 88 | if (actionDevice->GetBool(actionButton_.buttonId)) 89 | { 90 | if (firstDownTime_ == 0) 91 | { 92 | firstDownTime_ = manager_.GetTime(); 93 | firstDownX_ = posX; 94 | firstDownY_ = posY; 95 | } 96 | } 97 | else 98 | { 99 | oneShotReset_ = true; 100 | firstDownTime_ = 0; 101 | HandleButton(*this, *state_, delta, HoldTriggered, false); 102 | return; 103 | } 104 | 105 | if (positionValid 106 | && (Abs(posX - firstDownX_) > xTolerance_ || Abs(posY - firstDownY_) > yTolerance_)) 107 | { 108 | firstDownTime_ = 0; 109 | } 110 | 111 | bool downLongEnough = firstDownTime_ + timeSpan_ <= manager_.GetTime(); 112 | 113 | if (oneShot_) 114 | { 115 | if (downLongEnough && oneShotReset_) 116 | { 117 | HandleButton(*this, *state_, delta, HoldTriggered, true); 118 | oneShotReset_ = false; 119 | } 120 | else 121 | { 122 | HandleButton(*this, *state_, delta, HoldTriggered, false); 123 | } 124 | } 125 | else 126 | { 127 | HandleButton(*this, *state_, delta, HoldTriggered, downLongEnough); 128 | } 129 | } 130 | 131 | } 132 | 133 | #endif 134 | 135 | -------------------------------------------------------------------------------- /lib/source/gainput/gestures/GainputPinchGesture.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #ifdef GAINPUT_ENABLE_PINCH_GESTURE 6 | #include 7 | #include 8 | #include 9 | 10 | namespace gainput 11 | { 12 | 13 | PinchGesture::PinchGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant /*variant*/) : 14 | InputGesture(manager, device, index), 15 | pinching_(false) 16 | { 17 | downButton_.buttonId = InvalidDeviceButtonId; 18 | xAxis_.buttonId = InvalidDeviceButtonId; 19 | yAxis_.buttonId = InvalidDeviceButtonId; 20 | downButton2_.buttonId = InvalidDeviceButtonId; 21 | xAxis2_.buttonId = InvalidDeviceButtonId; 22 | yAxis2_.buttonId = InvalidDeviceButtonId; 23 | 24 | state_ = manager_.GetAllocator().New(manager.GetAllocator(), 2); 25 | GAINPUT_ASSERT(state_); 26 | previousState_ = manager_.GetAllocator().New(manager.GetAllocator(), 2); 27 | GAINPUT_ASSERT(previousState_); 28 | } 29 | 30 | PinchGesture::~PinchGesture() 31 | { 32 | manager_.GetAllocator().Delete(state_); 33 | manager_.GetAllocator().Delete(previousState_); 34 | } 35 | 36 | void 37 | PinchGesture::Initialize(DeviceId downDevice, DeviceButtonId downButton, 38 | DeviceId xAxisDevice, DeviceButtonId xAxis, 39 | DeviceId yAxisDevice, DeviceButtonId yAxis, 40 | DeviceId down2Device, DeviceButtonId downButton2, 41 | DeviceId xAxis2Device, DeviceButtonId xAxis2, 42 | DeviceId yAxis2Device, DeviceButtonId yAxis2) 43 | { 44 | downButton_.deviceId = downDevice; 45 | downButton_.buttonId = downButton; 46 | xAxis_.deviceId = xAxisDevice; 47 | xAxis_.buttonId = xAxis; 48 | yAxis_.deviceId = yAxisDevice; 49 | yAxis_.buttonId = yAxis; 50 | downButton2_.deviceId = down2Device; 51 | downButton2_.buttonId = downButton2; 52 | xAxis2_.deviceId = xAxis2Device; 53 | xAxis2_.buttonId = xAxis2; 54 | yAxis2_.deviceId = yAxis2Device; 55 | yAxis2_.buttonId = yAxis2; 56 | } 57 | 58 | void 59 | PinchGesture::InternalUpdate(InputDeltaState* delta) 60 | { 61 | if (downButton_.buttonId == InvalidDeviceButtonId 62 | || xAxis_.buttonId == InvalidDeviceButtonId 63 | || yAxis_.buttonId == InvalidDeviceButtonId 64 | || downButton2_.buttonId == InvalidDeviceButtonId 65 | || xAxis2_.buttonId == InvalidDeviceButtonId 66 | || yAxis2_.buttonId == InvalidDeviceButtonId) 67 | { 68 | return; 69 | } 70 | 71 | const InputDevice* downDevice = manager_.GetDevice(downButton_.deviceId); 72 | GAINPUT_ASSERT(downDevice); 73 | const bool isDown = downDevice->GetBool(downButton_.buttonId); 74 | 75 | const InputDevice* downDevice2 = manager_.GetDevice(downButton2_.deviceId); 76 | GAINPUT_ASSERT(downDevice2); 77 | const bool isDown2 = downDevice2->GetBool(downButton2_.buttonId); 78 | 79 | if (!isDown || !isDown2) 80 | { 81 | HandleButton(*this, *state_, delta, PinchTriggered, false); 82 | pinching_ = false; 83 | return; 84 | } 85 | 86 | HandleButton(*this, *state_, delta, PinchTriggered, true); 87 | 88 | const InputDevice* xAxisDevice = manager_.GetDevice(xAxis_.deviceId); 89 | GAINPUT_ASSERT(xAxisDevice); 90 | const float posX = xAxisDevice->GetFloat(xAxis_.buttonId); 91 | const InputDevice* yAxisDevice = manager_.GetDevice(yAxis_.deviceId); 92 | GAINPUT_ASSERT(yAxisDevice); 93 | const float posY = yAxisDevice->GetFloat(yAxis_.buttonId); 94 | 95 | const InputDevice* xAxis2Device = manager_.GetDevice(xAxis2_.deviceId); 96 | GAINPUT_ASSERT(xAxis2Device); 97 | const float posX2 = xAxis2Device->GetFloat(xAxis2_.buttonId); 98 | const InputDevice* yAxis2Device = manager_.GetDevice(yAxis2_.deviceId); 99 | GAINPUT_ASSERT(yAxis2Device); 100 | const float posY2 = yAxis2Device->GetFloat(yAxis2_.buttonId); 101 | 102 | const float xd = posX - posX2; 103 | const float yd = posY - posY2; 104 | const float dist = sqrtf(xd*xd + yd*yd); 105 | 106 | if (!pinching_ && dist > 0.0f) 107 | { 108 | pinching_ = true; 109 | initialDistance_ = dist; 110 | HandleAxis(*this, *state_, delta, PinchScale, 1.0f); 111 | return; 112 | } 113 | 114 | HandleAxis(*this, *state_, delta, PinchScale, dist / initialDistance_); 115 | } 116 | 117 | } 118 | 119 | #endif 120 | 121 | -------------------------------------------------------------------------------- /lib/source/gainput/gestures/GainputRotateGesture.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #ifdef GAINPUT_ENABLE_ROTATE_GESTURE 6 | #include 7 | #include 8 | 9 | #define _USE_MATH_DEFINES 10 | #include 11 | 12 | namespace gainput 13 | { 14 | 15 | RotateGesture::RotateGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant /*variant*/) : 16 | InputGesture(manager, device, index), 17 | rotating_(false) 18 | { 19 | downButton_.buttonId = InvalidDeviceButtonId; 20 | xAxis_.buttonId = InvalidDeviceButtonId; 21 | yAxis_.buttonId = InvalidDeviceButtonId; 22 | downButton2_.buttonId = InvalidDeviceButtonId; 23 | xAxis2_.buttonId = InvalidDeviceButtonId; 24 | yAxis2_.buttonId = InvalidDeviceButtonId; 25 | 26 | state_ = manager_.GetAllocator().New(manager.GetAllocator(), 2); 27 | GAINPUT_ASSERT(state_); 28 | previousState_ = manager_.GetAllocator().New(manager.GetAllocator(), 2); 29 | GAINPUT_ASSERT(previousState_); 30 | } 31 | 32 | RotateGesture::~RotateGesture() 33 | { 34 | manager_.GetAllocator().Delete(state_); 35 | manager_.GetAllocator().Delete(previousState_); 36 | } 37 | 38 | void 39 | RotateGesture::Initialize(DeviceId downDevice, DeviceButtonId downButton, 40 | DeviceId xAxisDevice, DeviceButtonId xAxis, 41 | DeviceId yAxisDevice, DeviceButtonId yAxis, 42 | DeviceId down2Device, DeviceButtonId downButton2, 43 | DeviceId xAxis2Device, DeviceButtonId xAxis2, 44 | DeviceId yAxis2Device, DeviceButtonId yAxis2) 45 | { 46 | downButton_.deviceId = downDevice; 47 | downButton_.buttonId = downButton; 48 | xAxis_.deviceId = xAxisDevice; 49 | xAxis_.buttonId = xAxis; 50 | yAxis_.deviceId = yAxisDevice; 51 | yAxis_.buttonId = yAxis; 52 | downButton2_.deviceId = down2Device; 53 | downButton2_.buttonId = downButton2; 54 | xAxis2_.deviceId = xAxis2Device; 55 | xAxis2_.buttonId = xAxis2; 56 | yAxis2_.deviceId = yAxis2Device; 57 | yAxis2_.buttonId = yAxis2; 58 | } 59 | 60 | void 61 | RotateGesture::InternalUpdate(InputDeltaState* delta) 62 | { 63 | if (downButton_.buttonId == InvalidDeviceButtonId 64 | || xAxis_.buttonId == InvalidDeviceButtonId 65 | || yAxis_.buttonId == InvalidDeviceButtonId 66 | || downButton2_.buttonId == InvalidDeviceButtonId 67 | || xAxis2_.buttonId == InvalidDeviceButtonId 68 | || yAxis2_.buttonId == InvalidDeviceButtonId) 69 | { 70 | return; 71 | } 72 | 73 | const InputDevice* downDevice = manager_.GetDevice(downButton_.deviceId); 74 | GAINPUT_ASSERT(downDevice); 75 | const bool isDown = downDevice->GetBool(downButton_.buttonId); 76 | 77 | const InputDevice* downDevice2 = manager_.GetDevice(downButton2_.deviceId); 78 | GAINPUT_ASSERT(downDevice2); 79 | const bool isDown2 = downDevice2->GetBool(downButton2_.buttonId); 80 | 81 | if (!isDown || !isDown2) 82 | { 83 | HandleButton(*this, *state_, delta, RotateTriggered, false); 84 | rotating_ = false; 85 | return; 86 | } 87 | 88 | HandleButton(*this, *state_, delta, RotateTriggered, true); 89 | 90 | const InputDevice* xAxisDevice = manager_.GetDevice(xAxis_.deviceId); 91 | GAINPUT_ASSERT(xAxisDevice); 92 | const float posX = xAxisDevice->GetFloat(xAxis_.buttonId); 93 | const InputDevice* yAxisDevice = manager_.GetDevice(yAxis_.deviceId); 94 | GAINPUT_ASSERT(yAxisDevice); 95 | const float posY = yAxisDevice->GetFloat(yAxis_.buttonId); 96 | 97 | const InputDevice* xAxis2Device = manager_.GetDevice(xAxis2_.deviceId); 98 | GAINPUT_ASSERT(xAxis2Device); 99 | const float posX2 = xAxis2Device->GetFloat(xAxis2_.buttonId); 100 | const InputDevice* yAxis2Device = manager_.GetDevice(yAxis2_.deviceId); 101 | GAINPUT_ASSERT(yAxis2Device); 102 | const float posY2 = yAxis2Device->GetFloat(yAxis2_.buttonId); 103 | 104 | const float angle = atan2f(posY2 - posY, posX2 - posX); 105 | 106 | if (!rotating_) 107 | { 108 | rotating_ = true; 109 | initialAngle_ = angle; 110 | HandleAxis(*this, *state_, delta, RotateAngle, 0.0f); 111 | return; 112 | } 113 | 114 | float currentAngle = angle - initialAngle_; 115 | if (currentAngle < 0.0f) 116 | { 117 | currentAngle += static_cast(M_PI)*2.0f; 118 | } 119 | 120 | HandleAxis(*this, *state_, delta, RotateAngle, currentAngle); 121 | } 122 | 123 | } 124 | 125 | #endif 126 | 127 | -------------------------------------------------------------------------------- /lib/source/gainput/gestures/GainputSimultaneouslyDownGesture.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #ifdef GAINPUT_ENABLE_SIMULTANEOUSLY_DOWN_GESTURE 6 | #include 7 | #include 8 | 9 | namespace gainput 10 | { 11 | 12 | SimultaneouslyDownGesture::SimultaneouslyDownGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant /*variant*/) : 13 | InputGesture(manager, device, index), 14 | buttons_(manager.GetAllocator()) 15 | { 16 | state_ = manager_.GetAllocator().New(manager.GetAllocator(), 1); 17 | GAINPUT_ASSERT(state_); 18 | previousState_ = manager_.GetAllocator().New(manager.GetAllocator(), 1); 19 | GAINPUT_ASSERT(previousState_); 20 | } 21 | 22 | SimultaneouslyDownGesture::~SimultaneouslyDownGesture() 23 | { 24 | manager_.GetAllocator().Delete(state_); 25 | manager_.GetAllocator().Delete(previousState_); 26 | } 27 | 28 | void 29 | SimultaneouslyDownGesture::AddButton(DeviceId device, DeviceButtonId button) 30 | { 31 | DeviceButtonSpec spec; 32 | spec.deviceId = device; 33 | spec.buttonId = button; 34 | buttons_.push_back(spec); 35 | } 36 | 37 | void 38 | SimultaneouslyDownGesture::ClearButtons() 39 | { 40 | buttons_.clear(); 41 | } 42 | 43 | void 44 | SimultaneouslyDownGesture::InternalUpdate(InputDeltaState* delta) 45 | { 46 | bool allDown = !buttons_.empty(); 47 | 48 | for (Array::const_iterator it = buttons_.begin(); 49 | it != buttons_.end() && allDown; 50 | ++it) 51 | { 52 | const InputDevice* device = manager_.GetDevice(it->deviceId); 53 | GAINPUT_ASSERT(device); 54 | allDown = allDown && device->GetBool(it->buttonId); 55 | } 56 | 57 | HandleButton(*this, *state_, delta, SimultaneouslyDownTriggered, allDown); 58 | } 59 | 60 | } 61 | 62 | #endif 63 | 64 | -------------------------------------------------------------------------------- /lib/source/gainput/gestures/GainputTapGesture.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #ifdef GAINPUT_ENABLE_TAP_GESTURE 6 | #include 7 | #include 8 | 9 | namespace gainput 10 | { 11 | 12 | TapGesture::TapGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant /*variant*/) : 13 | InputGesture(manager, device, index), 14 | firstDownTime_(0) 15 | { 16 | actionButton_.buttonId = InvalidDeviceButtonId; 17 | 18 | state_ = manager_.GetAllocator().New(manager.GetAllocator(), 1); 19 | GAINPUT_ASSERT(state_); 20 | previousState_ = manager_.GetAllocator().New(manager.GetAllocator(), 1); 21 | GAINPUT_ASSERT(previousState_); 22 | } 23 | 24 | TapGesture::~TapGesture() 25 | { 26 | manager_.GetAllocator().Delete(state_); 27 | manager_.GetAllocator().Delete(previousState_); 28 | } 29 | 30 | void 31 | TapGesture::Initialize(DeviceId actionButtonDevice, DeviceButtonId actionButton, uint64_t timeSpan) 32 | { 33 | actionButton_.deviceId = actionButtonDevice; 34 | actionButton_.buttonId = actionButton; 35 | timeSpan_ = timeSpan; 36 | } 37 | 38 | void 39 | TapGesture::InternalUpdate(InputDeltaState* delta) 40 | { 41 | if (actionButton_.buttonId == InvalidDeviceButtonId) 42 | { 43 | return; 44 | } 45 | 46 | const InputDevice* actionDevice = manager_.GetDevice(actionButton_.deviceId); 47 | GAINPUT_ASSERT(actionDevice); 48 | 49 | HandleButton(*this, *state_, delta, TapTriggered, false); 50 | 51 | if (actionDevice->GetBool(actionButton_.buttonId)) 52 | { 53 | if (firstDownTime_ == 0) 54 | { 55 | firstDownTime_ = manager_.GetTime(); 56 | } 57 | } 58 | else 59 | { 60 | if (firstDownTime_ > 0 && firstDownTime_ + timeSpan_ >= manager_.GetTime()) 61 | { 62 | HandleButton(*this, *state_, delta, TapTriggered, true); 63 | } 64 | firstDownTime_ = 0; 65 | } 66 | } 67 | 68 | } 69 | 70 | #endif 71 | 72 | -------------------------------------------------------------------------------- /lib/source/gainput/keyboard/GainputInputDeviceKeyboardImpl.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEKEYBOARDIMPL_H_ 3 | #define GAINPUTINPUTDEVICEKEYBOARDIMPL_H_ 4 | 5 | namespace gainput 6 | { 7 | 8 | class InputDeviceKeyboardImpl 9 | { 10 | public: 11 | virtual ~InputDeviceKeyboardImpl() { } 12 | virtual InputDevice::DeviceVariant GetVariant() const = 0; 13 | virtual InputDevice::DeviceState GetState() const { return InputDevice::DS_OK; } 14 | virtual void Update(InputDeltaState* delta) = 0; 15 | virtual InputState* GetNextInputState() { return 0; } 16 | 17 | virtual bool IsTextInputEnabled() const = 0; 18 | virtual void SetTextInputEnabled(bool enabled) = 0; 19 | virtual char GetNextCharacter() = 0; 20 | }; 21 | 22 | } 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /lib/source/gainput/keyboard/GainputInputDeviceKeyboardMac.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEKEYBOARDMAC_H_ 3 | #define GAINPUTINPUTDEVICEKEYBOARDMAC_H_ 4 | 5 | #include "GainputInputDeviceKeyboardImpl.h" 6 | 7 | namespace gainput 8 | { 9 | 10 | class InputDeviceKeyboardImplMac : public InputDeviceKeyboardImpl 11 | { 12 | public: 13 | InputDeviceKeyboardImplMac(InputManager& manager, InputDevice& device, InputState& state, InputState& previousState); 14 | ~InputDeviceKeyboardImplMac(); 15 | 16 | InputDevice::DeviceVariant GetVariant() const 17 | { 18 | return InputDevice::DV_RAW; 19 | } 20 | 21 | InputDevice::DeviceState GetState() const { return deviceState_; } 22 | 23 | void Update(InputDeltaState* delta) 24 | { 25 | delta_ = delta; 26 | *state_ = nextState_; 27 | } 28 | 29 | bool IsTextInputEnabled() const { return textInputEnabled_; } 30 | void SetTextInputEnabled(bool enabled) { textInputEnabled_ = enabled; } 31 | 32 | char GetNextCharacter() 33 | { 34 | if (!textBuffer_.CanGet()) 35 | { 36 | return 0; 37 | } 38 | return textBuffer_.Get(); 39 | } 40 | 41 | InputManager& manager_; 42 | InputDevice& device_; 43 | InputDevice::DeviceState deviceState_; 44 | bool textInputEnabled_; 45 | RingBuffer textBuffer_; 46 | HashMap dialect_; 47 | InputState* state_; 48 | InputState* previousState_; 49 | InputState nextState_; 50 | InputDeltaState* delta_; 51 | 52 | private: 53 | void* ioManager_; 54 | }; 55 | 56 | } 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /lib/source/gainput/keyboard/GainputInputDeviceKeyboardNull.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEKEYBOARDNULL_H_ 3 | #define GAINPUTINPUTDEVICEKEYBOARDNULL_H_ 4 | 5 | #include "GainputInputDeviceKeyboardImpl.h" 6 | 7 | namespace gainput 8 | { 9 | 10 | class InputDeviceKeyboardImplNull : public InputDeviceKeyboardImpl 11 | { 12 | public: 13 | InputDeviceKeyboardImplNull(InputManager& /*manager*/, DeviceId /*device*/) 14 | { 15 | } 16 | 17 | InputDevice::DeviceVariant GetVariant() const 18 | { 19 | return InputDevice::DV_NULL; 20 | } 21 | 22 | void Update(InputDeltaState* /*delta*/) 23 | { 24 | } 25 | 26 | bool IsTextInputEnabled() const { return false; } 27 | void SetTextInputEnabled(bool /*enabled*/) { } 28 | char GetNextCharacter() { return 0; } 29 | }; 30 | 31 | 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /lib/source/gainput/mouse/GainputInputDeviceMouseEvdev.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEMOUSEEVDEV_H_ 3 | #define GAINPUTINPUTDEVICEMOUSEEVDEV_H_ 4 | 5 | #include "../GainputHelpersEvdev.h" 6 | 7 | namespace gainput 8 | { 9 | 10 | class InputDeviceMouseImplEvdev : public InputDeviceMouseImpl 11 | { 12 | public: 13 | InputDeviceMouseImplEvdev(InputManager& manager, InputDevice& device, InputState& state, InputState& previousState) : 14 | manager_(manager), 15 | device_(device), 16 | state_(state), 17 | previousState_(previousState), 18 | fd_(-1), 19 | buttonsToReset_(manager.GetAllocator()) 20 | { 21 | unsigned matchingDeviceCount = 0; 22 | for (unsigned i = 0; i < EvdevDeviceCount; ++i) 23 | { 24 | fd_ = open(EvdevDeviceIds[i], O_RDONLY|O_NONBLOCK); 25 | if (fd_ == -1) 26 | { 27 | continue; 28 | } 29 | 30 | EvdevDevice evdev(fd_); 31 | 32 | if (evdev.IsValid()) 33 | { 34 | if (evdev.GetDeviceType() == InputDevice::DT_MOUSE) 35 | { 36 | if (matchingDeviceCount == manager_.GetDeviceCountByType(InputDevice::DT_MOUSE)) 37 | { 38 | break; 39 | } 40 | ++matchingDeviceCount; 41 | } 42 | } 43 | 44 | close(fd_); 45 | fd_ = -1; 46 | } 47 | } 48 | 49 | ~InputDeviceMouseImplEvdev() 50 | { 51 | if (fd_ != -1) 52 | { 53 | close(fd_); 54 | } 55 | } 56 | 57 | InputDevice::DeviceVariant GetVariant() const 58 | { 59 | return InputDevice::DV_RAW; 60 | } 61 | 62 | InputDevice::DeviceState GetState() const 63 | { 64 | return fd_ != -1 ? InputDevice::DS_OK : InputDevice::DS_UNAVAILABLE; 65 | } 66 | 67 | void Update(InputDeltaState* delta) 68 | { 69 | for (Array::const_iterator it = buttonsToReset_.begin(); 70 | it != buttonsToReset_.end(); 71 | ++it) 72 | { 73 | HandleButton(device_, state_, delta, *it, false); 74 | } 75 | buttonsToReset_.clear(); 76 | 77 | if (fd_ < 0) 78 | { 79 | return; 80 | } 81 | 82 | struct input_event event; 83 | 84 | for (;;) 85 | { 86 | int len = read(fd_, &event, sizeof(struct input_event)); 87 | if (len != sizeof(struct input_event)) 88 | { 89 | break; 90 | } 91 | 92 | if (event.type == EV_KEY) 93 | { 94 | int button = -1; 95 | if (event.code == BTN_LEFT) 96 | button = MouseButtonLeft; 97 | else if (event.code == BTN_MIDDLE) 98 | button = MouseButtonMiddle; 99 | else if (event.code == BTN_RIGHT) 100 | button = MouseButtonRight; 101 | else if (event.code == BTN_SIDE) 102 | button = MouseButton5; 103 | else if (event.code == BTN_EXTRA) 104 | button = MouseButton6; 105 | 106 | if (button != -1) 107 | { 108 | HandleButton(device_, state_, delta, DeviceButtonId(button), bool(event.value)); 109 | } 110 | } 111 | else if (event.type == EV_REL) 112 | { 113 | int button = -1; 114 | if (event.code == REL_X) 115 | button = MouseAxisX; 116 | else if (event.code == REL_Y) 117 | button = MouseAxisY; 118 | else if (event.code == REL_HWHEEL) 119 | button = MouseButton7; 120 | else if (event.code == REL_WHEEL) 121 | button = MouseButtonWheelUp; 122 | 123 | if (button == MouseButtonWheelUp) 124 | { 125 | if (event.value < 0) 126 | button = MouseButtonWheelDown; 127 | HandleButton(device_, state_, delta, DeviceButtonId(button), true); 128 | buttonsToReset_.push_back(button); 129 | } 130 | else if (button == MouseButton7) 131 | { 132 | if (event.value < 0) 133 | button = MouseButton8; 134 | HandleButton(device_, state_, delta, DeviceButtonId(button), true); 135 | buttonsToReset_.push_back(button); 136 | } 137 | else if (button != -1) 138 | { 139 | const DeviceButtonId buttonId(button); 140 | const float prevValue = previousState_.GetFloat(buttonId); 141 | HandleAxis(device_, state_, delta, DeviceButtonId(button), prevValue + float(event.value)); 142 | } 143 | } 144 | } 145 | } 146 | 147 | 148 | 149 | private: 150 | InputManager& manager_; 151 | InputDevice& device_; 152 | InputState& state_; 153 | InputState& previousState_; 154 | int fd_; 155 | Array buttonsToReset_; 156 | }; 157 | 158 | } 159 | 160 | #endif 161 | 162 | -------------------------------------------------------------------------------- /lib/source/gainput/mouse/GainputInputDeviceMouseImpl.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEMOUSEIMPL_H_ 3 | #define GAINPUTINPUTDEVICEMOUSEIMPL_H_ 4 | 5 | namespace gainput 6 | { 7 | 8 | class InputDeviceMouseImpl 9 | { 10 | public: 11 | virtual ~InputDeviceMouseImpl() { } 12 | virtual InputDevice::DeviceVariant GetVariant() const = 0; 13 | virtual InputDevice::DeviceState GetState() const { return InputDevice::DS_OK; } 14 | virtual void Update(InputDeltaState* delta) = 0; 15 | }; 16 | 17 | } 18 | 19 | #endif 20 | 21 | -------------------------------------------------------------------------------- /lib/source/gainput/mouse/GainputInputDeviceMouseLinux.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEMOUSELINUX_H_ 3 | #define GAINPUTINPUTDEVICEMOUSELINUX_H_ 4 | 5 | #include 6 | 7 | #include "GainputInputDeviceMouseImpl.h" 8 | #include 9 | 10 | namespace gainput 11 | { 12 | 13 | class InputDeviceMouseImplLinux : public InputDeviceMouseImpl 14 | { 15 | public: 16 | InputDeviceMouseImplLinux(InputManager& manager, InputDevice& device, InputState& state, InputState& previousState) : 17 | manager_(manager), 18 | device_(device), 19 | state_(&state), 20 | previousState_(&previousState), 21 | nextState_(manager.GetAllocator(), MouseButtonCount + MouseAxisCount), 22 | delta_(0) 23 | { 24 | const size_t size = sizeof(bool)*MouseButtonCount; 25 | isWheel_ = static_cast(manager_.GetAllocator().Allocate(size)); 26 | GAINPUT_ASSERT(isWheel_); 27 | memset(isWheel_, 0, size); 28 | pressedThisFrame_ = static_cast(manager_.GetAllocator().Allocate(size)); 29 | GAINPUT_ASSERT(pressedThisFrame_); 30 | } 31 | 32 | ~InputDeviceMouseImplLinux() 33 | { 34 | manager_.GetAllocator().Deallocate(isWheel_); 35 | manager_.GetAllocator().Deallocate(pressedThisFrame_); 36 | } 37 | 38 | InputDevice::DeviceVariant GetVariant() const 39 | { 40 | return InputDevice::DV_STANDARD; 41 | } 42 | 43 | void Update(InputDeltaState* delta) 44 | { 45 | delta_ = delta; 46 | 47 | // Reset mouse wheel buttons 48 | for (unsigned i = 0; i < MouseButtonCount; ++i) 49 | { 50 | const DeviceButtonId buttonId = i; 51 | const bool oldValue = previousState_->GetBool(buttonId); 52 | if (isWheel_[i] && oldValue) 53 | { 54 | const bool pressed = false; 55 | HandleButton(device_, nextState_, delta_, buttonId, pressed); 56 | } 57 | } 58 | 59 | *state_ = nextState_; 60 | 61 | memset(pressedThisFrame_, 0, sizeof(bool) * MouseButtonCount); 62 | } 63 | 64 | void HandleEvent(XEvent& event) 65 | { 66 | GAINPUT_ASSERT(state_); 67 | GAINPUT_ASSERT(previousState_); 68 | 69 | switch (event.type) 70 | { 71 | case MotionNotify: 72 | { 73 | const XMotionEvent& motionEvent = event.xmotion; 74 | const float x = float(motionEvent.x)/float(manager_.GetDisplayWidth()); 75 | const float y = float(motionEvent.y)/float(manager_.GetDisplayHeight()); 76 | HandleAxis(device_, nextState_, delta_, MouseAxisX, x); 77 | HandleAxis(device_, nextState_, delta_, MouseAxisY, y); 78 | break; 79 | } 80 | case ButtonPress: 81 | case ButtonRelease: 82 | { 83 | const XButtonEvent& buttonEvent = event.xbutton; 84 | GAINPUT_ASSERT(buttonEvent.button > 0); 85 | const DeviceButtonId buttonId = buttonEvent.button-1; 86 | GAINPUT_ASSERT(buttonId <= MouseButtonMax); 87 | const bool pressed = event.type == ButtonPress; 88 | 89 | if (!pressed && pressedThisFrame_[buttonId]) 90 | { 91 | // This is a mouse wheel button. Ignore release now, reset next frame. 92 | isWheel_[buttonId] = true; 93 | } 94 | else if (buttonEvent.button < MouseButtonCount) 95 | { 96 | HandleButton(device_, nextState_, delta_, buttonId, pressed); 97 | } 98 | 99 | if (pressed) 100 | { 101 | pressedThisFrame_[buttonId] = true; 102 | } 103 | break; 104 | } 105 | } 106 | } 107 | 108 | private: 109 | InputManager& manager_; 110 | InputDevice& device_; 111 | bool* isWheel_; 112 | bool* pressedThisFrame_; 113 | InputState* state_; 114 | InputState* previousState_; 115 | InputState nextState_; 116 | InputDeltaState* delta_; 117 | }; 118 | 119 | } 120 | 121 | #endif 122 | 123 | -------------------------------------------------------------------------------- /lib/source/gainput/mouse/GainputInputDeviceMouseMac.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEMOUSEMAC_H_ 3 | #define GAINPUTINPUTDEVICEMOUSEMAC_H_ 4 | 5 | #include "GainputInputDeviceMouseImpl.h" 6 | 7 | namespace gainput 8 | { 9 | 10 | class InputDeviceMouseImplMac : public InputDeviceMouseImpl 11 | { 12 | public: 13 | InputDeviceMouseImplMac(InputManager& manager, InputDevice& device, InputState& state, InputState& previousState); 14 | ~InputDeviceMouseImplMac(); 15 | 16 | InputDevice::DeviceVariant GetVariant() const 17 | { 18 | return InputDevice::DV_STANDARD; 19 | } 20 | 21 | void Update(InputDeltaState* delta); 22 | 23 | InputManager& manager_; 24 | InputDevice& device_; 25 | InputState* state_; 26 | InputState* previousState_; 27 | InputState nextState_; 28 | InputDeltaState* delta_; 29 | 30 | void* eventTap_; 31 | }; 32 | 33 | } 34 | 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /lib/source/gainput/mouse/GainputInputDeviceMouseNull.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEMOUSENULL_H_ 3 | #define GAINPUTINPUTDEVICEMOUSENULL_H_ 4 | 5 | namespace gainput 6 | { 7 | 8 | class InputDeviceMouseImplNull : public InputDeviceMouseImpl 9 | { 10 | public: 11 | InputDeviceMouseImplNull(InputManager& /*manager*/, DeviceId /*device*/) 12 | { 13 | } 14 | 15 | InputDevice::DeviceVariant GetVariant() const 16 | { 17 | return InputDevice::DV_NULL; 18 | } 19 | 20 | void Update(InputDeltaState* /*delta*/) 21 | { 22 | } 23 | }; 24 | 25 | } 26 | 27 | #endif 28 | 29 | -------------------------------------------------------------------------------- /lib/source/gainput/mouse/GainputInputDeviceMouseWin.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEMOUSEWIN_H_ 3 | #define GAINPUTINPUTDEVICEMOUSEWIN_H_ 4 | 5 | #include "GainputInputDeviceMouseImpl.h" 6 | #include 7 | 8 | #include "../GainputWindows.h" 9 | 10 | namespace gainput 11 | { 12 | 13 | class InputDeviceMouseImplWin : public InputDeviceMouseImpl 14 | { 15 | public: 16 | InputDeviceMouseImplWin(InputManager& manager, InputDevice& device, InputState& state, InputState& previousState) : 17 | manager_(manager), 18 | device_(device), 19 | state_(&state), 20 | previousState_(&previousState), 21 | nextState_(manager.GetAllocator(), MouseButtonCount + MouseAxisCount), 22 | delta_(0) 23 | { 24 | } 25 | 26 | InputDevice::DeviceVariant GetVariant() const 27 | { 28 | return InputDevice::DV_STANDARD; 29 | } 30 | 31 | void Update(InputDeltaState* delta) 32 | { 33 | delta_ = delta; 34 | 35 | // Reset mouse wheel buttons 36 | HandleButton(device_, nextState_, delta_, MouseButton3, false); 37 | HandleButton(device_, nextState_, delta_, MouseButton4, false); 38 | 39 | *state_ = nextState_; 40 | } 41 | 42 | void HandleMessage(const MSG& msg) 43 | { 44 | GAINPUT_ASSERT(state_); 45 | GAINPUT_ASSERT(previousState_); 46 | 47 | DeviceButtonId buttonId; 48 | bool pressed = false; 49 | bool moveMessage = false; 50 | int ax = -1; 51 | int ay = -1; 52 | switch (msg.message) 53 | { 54 | case WM_LBUTTONDOWN: 55 | buttonId = MouseButtonLeft; 56 | pressed = true; 57 | break; 58 | case WM_LBUTTONUP: 59 | buttonId = MouseButtonLeft; 60 | pressed = false; 61 | break; 62 | case WM_RBUTTONDOWN: 63 | buttonId = MouseButtonRight; 64 | pressed = true; 65 | break; 66 | case WM_RBUTTONUP: 67 | buttonId = MouseButtonRight; 68 | pressed = false; 69 | break; 70 | case WM_MBUTTONDOWN: 71 | buttonId = MouseButtonMiddle; 72 | pressed = true; 73 | break; 74 | case WM_MBUTTONUP: 75 | buttonId = MouseButtonMiddle; 76 | pressed = false; 77 | break; 78 | case WM_XBUTTONDOWN: 79 | buttonId = MouseButton4 + GET_XBUTTON_WPARAM(msg.wParam); 80 | pressed = true; 81 | break; 82 | case WM_XBUTTONUP: 83 | buttonId = MouseButton4 + GET_XBUTTON_WPARAM(msg.wParam); 84 | pressed = false; 85 | break; 86 | case WM_MOUSEMOVE: 87 | moveMessage = true; 88 | ax = GET_X_LPARAM(msg.lParam); 89 | ay = GET_Y_LPARAM(msg.lParam); 90 | break; 91 | case WM_MOUSEWHEEL: 92 | { 93 | int wheel = GET_WHEEL_DELTA_WPARAM(msg.wParam); 94 | if (wheel < 0) 95 | { 96 | buttonId = MouseButton4; 97 | pressed = true; 98 | } 99 | else if (wheel > 0) 100 | { 101 | buttonId = MouseButton3; 102 | pressed = true; 103 | } 104 | break; 105 | } 106 | default: // Non-mouse message 107 | return; 108 | } 109 | 110 | if (moveMessage) 111 | { 112 | float x = float(ax)/float(manager_.GetDisplayWidth()); 113 | float y = float(ay)/float(manager_.GetDisplayHeight()); 114 | HandleAxis(device_, nextState_, delta_, MouseAxisX, x); 115 | HandleAxis(device_, nextState_, delta_, MouseAxisY, y); 116 | } 117 | else 118 | { 119 | HandleButton(device_, nextState_, delta_, buttonId, pressed); 120 | } 121 | } 122 | 123 | private: 124 | InputManager& manager_; 125 | InputDevice& device_; 126 | InputState* state_; 127 | InputState* previousState_; 128 | InputState nextState_; 129 | InputDeltaState* delta_; 130 | }; 131 | 132 | } 133 | 134 | #endif 135 | 136 | -------------------------------------------------------------------------------- /lib/source/gainput/mouse/GainputMouseInfo.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTMOUSEINFO_H_ 3 | #define GAINPUTMOUSEINFO_H_ 4 | 5 | namespace gainput 6 | { 7 | 8 | namespace 9 | { 10 | struct DeviceButtonInfo 11 | { 12 | ButtonType type; 13 | const char* name; 14 | }; 15 | 16 | DeviceButtonInfo deviceButtonInfos[] = 17 | { 18 | { BT_BOOL, "mouse_left" }, 19 | { BT_BOOL, "mouse_middle" }, 20 | { BT_BOOL, "mouse_right" }, 21 | { BT_BOOL, "mouse_3" }, 22 | { BT_BOOL, "mouse_4" }, 23 | { BT_BOOL, "mouse_5" }, 24 | { BT_BOOL, "mouse_6" }, 25 | { BT_BOOL, "mouse_7" }, 26 | { BT_BOOL, "mouse_8" }, 27 | { BT_BOOL, "mouse_9" }, 28 | { BT_BOOL, "mouse_10" }, 29 | { BT_BOOL, "mouse_11" }, 30 | { BT_BOOL, "mouse_12" }, 31 | { BT_BOOL, "mouse_13" }, 32 | { BT_BOOL, "mouse_14" }, 33 | { BT_BOOL, "mouse_15" }, 34 | { BT_BOOL, "mouse_16" }, 35 | { BT_BOOL, "mouse_17" }, 36 | { BT_BOOL, "mouse_18" }, 37 | { BT_BOOL, "mouse_19" }, 38 | { BT_BOOL, "mouse_20" }, 39 | { BT_FLOAT, "mouse_x" }, 40 | { BT_FLOAT, "mouse_y" } 41 | }; 42 | } 43 | 44 | 45 | } 46 | 47 | #endif 48 | 49 | -------------------------------------------------------------------------------- /lib/source/gainput/pad/GainputInputDevicePadAndroid.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEPADANDROID_H_ 3 | #define GAINPUTINPUTDEVICEPADANDROID_H_ 4 | 5 | #include "GainputInputDevicePadImpl.h" 6 | #include 7 | 8 | namespace gainput 9 | { 10 | 11 | class InputDevicePadImplAndroid : public InputDevicePadImpl 12 | { 13 | public: 14 | InputDevicePadImplAndroid(InputManager& manager, InputDevice& device, unsigned index, InputState& state, InputState& previousState) : 15 | manager_(manager), 16 | device_(device), 17 | state_(&state), 18 | previousState_(&previousState), 19 | nextState_(manager.GetAllocator(), PadButtonMax_), 20 | delta_(0), 21 | index_(index), 22 | deviceState_(InputDevice::DS_UNAVAILABLE) 23 | { 24 | (void)previousState; 25 | GAINPUT_ASSERT(index_ < MaxPadCount); 26 | } 27 | 28 | ~InputDevicePadImplAndroid() 29 | { 30 | } 31 | 32 | InputDevice::DeviceVariant GetVariant() const 33 | { 34 | return InputDevice::DV_STANDARD; 35 | } 36 | 37 | void Update(InputDeltaState* delta) 38 | { 39 | delta_ = delta; 40 | *state_ = nextState_; 41 | } 42 | 43 | InputDevice::DeviceState GetState() const 44 | { 45 | return deviceState_; 46 | } 47 | 48 | void SetState(InputDevice::DeviceState state) 49 | { 50 | deviceState_ = state; 51 | } 52 | 53 | bool IsValidButton(DeviceButtonId deviceButton) const 54 | { 55 | return deviceButton < PadButtonMax_; 56 | } 57 | 58 | bool Vibrate(float /*leftMotor*/, float /*rightMotor*/) 59 | { 60 | return false; // TODO 61 | } 62 | 63 | InputState* GetNextInputState() { return &nextState_; } 64 | 65 | private: 66 | InputManager& manager_; 67 | InputDevice& device_; 68 | InputState* state_; 69 | InputState* previousState_; 70 | InputState nextState_; 71 | InputDeltaState* delta_; 72 | unsigned index_; 73 | InputDevice::DeviceState deviceState_; 74 | 75 | }; 76 | 77 | } 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /lib/source/gainput/pad/GainputInputDevicePadImpl.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEPADIMPL_H_ 3 | #define GAINPUTINPUTDEVICEPADIMPL_H_ 4 | 5 | namespace gainput 6 | { 7 | 8 | class InputDevicePadImpl 9 | { 10 | public: 11 | virtual ~InputDevicePadImpl() { } 12 | virtual InputDevice::DeviceVariant GetVariant() const = 0; 13 | virtual InputDevice::DeviceState GetState() const { return InputDevice::DS_OK; } 14 | virtual void Update(InputDeltaState* delta) = 0; 15 | virtual bool IsValidButton(DeviceButtonId deviceButton) const = 0; 16 | virtual bool Vibrate(float leftMotor, float rightMotor) = 0; 17 | virtual InputState* GetNextInputState() { return 0; } 18 | }; 19 | 20 | } 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /lib/source/gainput/pad/GainputInputDevicePadIos.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEPADIOS_H_ 3 | #define GAINPUTINPUTDEVICEPADIOS_H_ 4 | 5 | #include 6 | 7 | namespace gainput 8 | { 9 | 10 | class InputDevicePadImplIos : public InputDevicePadImpl 11 | { 12 | public: 13 | InputDevicePadImplIos(InputManager& manager, InputDevice& device, unsigned index, InputState& state, InputState& previousState); 14 | ~InputDevicePadImplIos(); 15 | 16 | InputDevice::DeviceVariant GetVariant() const 17 | { 18 | return InputDevice::DV_STANDARD; 19 | } 20 | 21 | void Update(InputDeltaState* delta); 22 | 23 | InputDevice::DeviceState GetState() const 24 | { 25 | return deviceState_; 26 | } 27 | 28 | bool IsValidButton(DeviceButtonId deviceButton) const; 29 | 30 | typedef gainput::Array GlobalControllerList; 31 | static GlobalControllerList* mappedControllers_; 32 | 33 | bool Vibrate(float leftMotor, float rightMotor) 34 | { 35 | return false; 36 | } 37 | 38 | private: 39 | InputManager& manager_; 40 | InputDevice& device_; 41 | unsigned index_; 42 | InputState& state_; 43 | InputState& previousState_; 44 | InputDevice::DeviceState deviceState_; 45 | 46 | bool pausePressed_; 47 | bool isMicro_; 48 | bool isNormal_; 49 | bool isExtended_; 50 | bool supportsMotion_; 51 | bool isRemote_; 52 | void* gcController_; 53 | 54 | void UpdateRemote_(InputDeltaState* delta); 55 | void UpdateGamepad_(InputDeltaState* delta); 56 | }; 57 | 58 | } 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /lib/source/gainput/pad/GainputInputDevicePadMac.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEPADMAC_H_ 3 | #define GAINPUTINPUTDEVICEPADMAC_H_ 4 | 5 | 6 | namespace gainput 7 | { 8 | 9 | class InputDevicePadImplMac : public InputDevicePadImpl 10 | { 11 | public: 12 | InputDevicePadImplMac(InputManager& manager, InputDevice& device, unsigned index, InputState& state, InputState& previousState); 13 | ~InputDevicePadImplMac(); 14 | 15 | InputDevice::DeviceVariant GetVariant() const 16 | { 17 | return InputDevice::DV_STANDARD; 18 | } 19 | 20 | void Update(InputDeltaState* delta); 21 | 22 | InputDevice::DeviceState GetState() const 23 | { 24 | return deviceState_; 25 | } 26 | 27 | bool IsValidButton(DeviceButtonId deviceButton) const; 28 | 29 | bool Vibrate(float leftMotor, float rightMotor) 30 | { 31 | return false; 32 | } 33 | 34 | HashMap buttonDialect_; 35 | HashMap axisDialect_; 36 | float minAxis_; 37 | float maxAxis_; 38 | float minTriggerAxis_; 39 | float maxTriggerAxis_; 40 | InputManager& manager_; 41 | InputDevice& device_; 42 | unsigned index_; 43 | InputState& state_; 44 | InputState& previousState_; 45 | InputState nextState_; 46 | InputDeltaState* delta_; 47 | InputDevice::DeviceState deviceState_; 48 | 49 | void* ioManager_; 50 | 51 | private: 52 | }; 53 | 54 | } 55 | 56 | #endif 57 | 58 | -------------------------------------------------------------------------------- /lib/source/gainput/pad/GainputInputDevicePadNull.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICEPADNULL_H_ 3 | #define GAINPUTINPUTDEVICEPADNULL_H_ 4 | 5 | 6 | namespace gainput 7 | { 8 | 9 | class InputDevicePadImplNull : public InputDevicePadImpl 10 | { 11 | public: 12 | InputDevicePadImplNull(InputManager& manager, InputDevice& device, unsigned index, InputState& state, InputState& previousState) 13 | { 14 | } 15 | 16 | InputDevice::DeviceVariant GetVariant() const 17 | { 18 | return InputDevice::DV_NULL; 19 | } 20 | 21 | void Update(InputDeltaState* /*delta*/) 22 | { 23 | } 24 | 25 | InputDevice::DeviceState GetState() const 26 | { 27 | return InputDevice::DS_OK; 28 | } 29 | 30 | bool IsValidButton(DeviceButtonId /*deviceButton*/) const 31 | { 32 | return false; 33 | } 34 | 35 | bool Vibrate(float /*leftMotor*/, float /*rightMotor*/) 36 | { 37 | return false; 38 | } 39 | }; 40 | 41 | } 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /lib/source/gainput/recorder/GainputInputPlayer.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #ifdef GAINPUT_ENABLE_RECORDER 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | namespace gainput 12 | { 13 | 14 | InputPlayer::InputPlayer(InputManager& manager, InputRecording* recording) : 15 | manager_(manager), 16 | isPlaying_(false), 17 | recording_(recording), 18 | startTime_(0), 19 | devicesToReset_(manager.GetAllocator()) 20 | { 21 | playingModifierId_ = manager_.AddDeviceStateModifier(this); 22 | } 23 | 24 | InputPlayer::~InputPlayer() 25 | { 26 | manager_.RemoveDeviceStateModifier(playingModifierId_); 27 | } 28 | 29 | void 30 | InputPlayer::Update(InputDeltaState* delta) 31 | { 32 | if (!isPlaying_) 33 | { 34 | return; 35 | } 36 | 37 | uint64_t now = manager_.GetTime(); 38 | GAINPUT_ASSERT(now >= startTime_); 39 | now -= startTime_; 40 | 41 | RecordedDeviceButtonChange change; 42 | while (recording_->GetNextChange(now, change)) 43 | { 44 | InputDevice* device = manager_.GetDevice(change.deviceId); 45 | 46 | GAINPUT_ASSERT(device); 47 | GAINPUT_ASSERT(device->IsValidButtonId(change.buttonId)); 48 | GAINPUT_ASSERT(device->GetInputState()); 49 | GAINPUT_ASSERT(device->GetPreviousInputState()); 50 | 51 | if (!device->IsSynced()) 52 | { 53 | device->SetSynced(true); 54 | devicesToReset_.push_back(change.deviceId); 55 | } 56 | 57 | if (device->GetButtonType(change.buttonId) == BT_BOOL) 58 | { 59 | HandleButton(*device, *device->GetInputState(), delta, change.buttonId, change.b); 60 | } 61 | else 62 | { 63 | HandleAxis(*device, *device->GetInputState(), delta, change.buttonId, change.f); 64 | } 65 | } 66 | 67 | if (now >= recording_->GetDuration()) 68 | { 69 | #ifdef GAINPUT_DEBUG 70 | GAINPUT_LOG("GAINPUT: Recording is over. Stopping playback.\n"); 71 | #endif 72 | Stop(); 73 | } 74 | } 75 | 76 | void 77 | InputPlayer::SetRecording(InputRecording* recording) 78 | { 79 | GAINPUT_ASSERT(!isPlaying_); 80 | recording_ = recording; 81 | } 82 | 83 | void 84 | InputPlayer::Start() 85 | { 86 | GAINPUT_ASSERT(recording_); 87 | isPlaying_ = true; 88 | startTime_ = manager_.GetTime(); 89 | recording_->Reset(); 90 | } 91 | 92 | void 93 | InputPlayer::Stop() 94 | { 95 | isPlaying_ = false; 96 | 97 | for (Array::const_iterator it = devicesToReset_.begin(); 98 | it != devicesToReset_.end(); 99 | ++it) 100 | { 101 | InputDevice* device = manager_.GetDevice(*it); 102 | GAINPUT_ASSERT(device); 103 | device->SetSynced(false); 104 | } 105 | devicesToReset_.clear(); 106 | } 107 | 108 | } 109 | 110 | #endif 111 | 112 | -------------------------------------------------------------------------------- /lib/source/gainput/recorder/GainputInputRecorder.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #ifdef GAINPUT_ENABLE_RECORDER 5 | 6 | namespace gainput 7 | { 8 | 9 | namespace 10 | { 11 | class RecordingListener : public InputListener 12 | { 13 | public: 14 | RecordingListener(InputManager& manager, InputRecorder& recorder) : 15 | manager_(manager), 16 | recorder_(recorder) 17 | { } 18 | 19 | bool OnDeviceButtonBool(gainput::DeviceId deviceId, gainput::DeviceButtonId deviceButton, bool /*oldValue*/, bool newValue) 20 | { 21 | if (!recorder_.IsDeviceToRecord(deviceId)) 22 | { 23 | return true; 24 | } 25 | 26 | InputRecording* recording = recorder_.GetRecording(); 27 | GAINPUT_ASSERT(recording); 28 | GAINPUT_ASSERT(manager_.GetTime() >= recorder_.GetStartTime()); 29 | const uint64_t time = manager_.GetTime() - recorder_.GetStartTime(); 30 | recording->AddChange(time, deviceId, deviceButton, newValue); 31 | 32 | return true; 33 | } 34 | 35 | bool OnDeviceButtonFloat(gainput::DeviceId deviceId, gainput::DeviceButtonId deviceButton, float /*oldValue*/, float newValue) 36 | { 37 | if (!recorder_.IsDeviceToRecord(deviceId)) 38 | { 39 | return true; 40 | } 41 | 42 | InputRecording* recording = recorder_.GetRecording(); 43 | GAINPUT_ASSERT(recording); 44 | GAINPUT_ASSERT(manager_.GetTime() >= recorder_.GetStartTime()); 45 | const uint64_t time = manager_.GetTime() - recorder_.GetStartTime(); 46 | recording->AddChange(time, deviceId, deviceButton, newValue); 47 | 48 | return true; 49 | } 50 | 51 | private: 52 | InputManager& manager_; 53 | InputRecorder& recorder_; 54 | 55 | }; 56 | } 57 | 58 | 59 | InputRecorder::InputRecorder(InputManager& manager) : 60 | manager_(manager), 61 | isRecording_(false), 62 | recordingListener_(0), 63 | recording_(0), 64 | startTime_(0), 65 | recordedDevices_(manager.GetAllocator()) 66 | { 67 | } 68 | 69 | InputRecorder::~InputRecorder() 70 | { 71 | Stop(); 72 | 73 | if (recording_) 74 | { 75 | manager_.GetAllocator().Delete(recording_); 76 | } 77 | } 78 | 79 | void 80 | InputRecorder::Start() 81 | { 82 | isRecording_ = true; 83 | 84 | if (recording_) 85 | { 86 | recording_->Clear(); 87 | } 88 | else 89 | { 90 | recording_ = manager_.GetAllocator().New(manager_.GetAllocator()); 91 | } 92 | 93 | startTime_ = manager_.GetTime(); 94 | 95 | recordingListener_ = manager_.GetAllocator().New(manager_, *this); 96 | recordingListenerId_ = manager_.AddListener(recordingListener_); 97 | 98 | // Record the initial state 99 | for (InputManager::iterator it = manager_.begin(); 100 | it != manager_.end(); 101 | ++it) 102 | { 103 | InputDevice* device = it->second; 104 | const DeviceId deviceId = device->GetDeviceId(); 105 | 106 | if (!IsDeviceToRecord(deviceId)) 107 | { 108 | continue; 109 | } 110 | 111 | GAINPUT_ASSERT(device->GetInputState()); 112 | for (DeviceButtonId buttonId = 0; buttonId < device->GetInputState()->GetButtonCount(); ++buttonId) 113 | { 114 | if (device->IsValidButtonId(buttonId)) 115 | { 116 | if (device->GetButtonType(buttonId) == BT_BOOL) 117 | { 118 | recording_->AddChange(0, deviceId, buttonId, device->GetBool(buttonId)); 119 | } 120 | else 121 | { 122 | recording_->AddChange(0, deviceId, buttonId, device->GetFloat(buttonId)); 123 | } 124 | } 125 | } 126 | } 127 | } 128 | 129 | void 130 | InputRecorder::Stop() 131 | { 132 | if (!isRecording_) 133 | { 134 | return; 135 | } 136 | 137 | isRecording_ = false; 138 | manager_.RemoveListener(recordingListenerId_); 139 | manager_.GetAllocator().Delete(recordingListener_); 140 | recordingListener_ = 0; 141 | } 142 | 143 | } 144 | 145 | #endif 146 | 147 | -------------------------------------------------------------------------------- /lib/source/gainput/touch/GainputInputDeviceTouchAndroid.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICETOUCHANDROID_H_ 3 | #define GAINPUTINPUTDEVICETOUCHANDROID_H_ 4 | 5 | #include 6 | 7 | #include "GainputInputDeviceTouchImpl.h" 8 | #include "GainputTouchInfo.h" 9 | #include 10 | 11 | namespace gainput 12 | { 13 | 14 | class InputDeviceTouchImplAndroid : public InputDeviceTouchImpl 15 | { 16 | public: 17 | InputDeviceTouchImplAndroid(InputManager& manager, InputDevice& device, InputState& state, InputState& previousState) : 18 | manager_(manager), 19 | device_(device), 20 | state_(&state), 21 | previousState_(&previousState), 22 | nextState_(manager.GetAllocator(), TouchPointCount*TouchDataElems), 23 | delta_(0) 24 | { 25 | } 26 | 27 | InputDevice::DeviceVariant GetVariant() const 28 | { 29 | return InputDevice::DV_STANDARD; 30 | } 31 | 32 | void Update(InputDeltaState* delta) 33 | { 34 | delta_ = delta; 35 | *state_ = nextState_; 36 | } 37 | 38 | InputDevice::DeviceState GetState() const { return InputDevice::DS_OK; } 39 | 40 | int32_t HandleInput(AInputEvent* event) 41 | { 42 | GAINPUT_ASSERT(state_); 43 | GAINPUT_ASSERT(previousState_); 44 | GAINPUT_ASSERT(event); 45 | 46 | if (AInputEvent_getType(event) != AINPUT_EVENT_TYPE_MOTION) 47 | { 48 | return 0; 49 | } 50 | 51 | for (unsigned i = 0; i < AMotionEvent_getPointerCount(event) && i < TouchPointCount; ++i) 52 | { 53 | GAINPUT_ASSERT(i < TouchPointCount); 54 | const float x = AMotionEvent_getX(event, i); 55 | const float y = AMotionEvent_getY(event, i); 56 | const int32_t w = manager_.GetDisplayWidth(); 57 | const int32_t h = manager_.GetDisplayHeight(); 58 | HandleFloat(Touch0X + i*TouchDataElems, x/float(w)); 59 | HandleFloat(Touch0Y + i*TouchDataElems, y/float(h)); 60 | const int motionAction = AMotionEvent_getAction(event); 61 | const bool down = (motionAction == AMOTION_EVENT_ACTION_DOWN || motionAction == AMOTION_EVENT_ACTION_MOVE); 62 | HandleBool(Touch0Down + i*TouchDataElems, down); 63 | HandleFloat(Touch0Pressure + i*TouchDataElems, AMotionEvent_getPressure(event, i)); 64 | #ifdef GAINPUT_DEBUG 65 | GAINPUT_LOG("Touch %i) x: %f, y: %f, w: %i, h: %i, action: %d\n", i, x, y, w, h, motionAction); 66 | #endif 67 | } 68 | 69 | return 1; 70 | } 71 | 72 | InputState* GetNextInputState() 73 | { 74 | return &nextState_; 75 | } 76 | 77 | private: 78 | InputManager& manager_; 79 | InputDevice& device_; 80 | InputState* state_; 81 | InputState* previousState_; 82 | InputState nextState_; 83 | InputDeltaState* delta_; 84 | 85 | void HandleBool(DeviceButtonId buttonId, bool value) 86 | { 87 | HandleButton(device_, nextState_, delta_, buttonId, value); 88 | } 89 | 90 | void HandleFloat(DeviceButtonId buttonId, float value) 91 | { 92 | HandleAxis(device_, nextState_, delta_, buttonId, value); 93 | } 94 | }; 95 | 96 | } 97 | 98 | #endif 99 | 100 | -------------------------------------------------------------------------------- /lib/source/gainput/touch/GainputInputDeviceTouchImpl.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICETOUCHIMPL_H_ 3 | #define GAINPUTINPUTDEVICETOUCHIMPL_H_ 4 | 5 | namespace gainput 6 | { 7 | 8 | class InputDeviceTouchImpl 9 | { 10 | public: 11 | virtual ~InputDeviceTouchImpl() { } 12 | virtual InputDevice::DeviceVariant GetVariant() const = 0; 13 | virtual InputDevice::DeviceState GetState() const = 0; 14 | virtual void Update(InputDeltaState* delta) = 0; 15 | virtual bool SupportsPressure() const { return false; } 16 | virtual InputState* GetNextInputState() { return 0; } 17 | }; 18 | 19 | } 20 | 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /lib/source/gainput/touch/GainputInputDeviceTouchIos.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICETOUCHANDROID_H_ 3 | #define GAINPUTINPUTDEVICETOUCHANDROID_H_ 4 | 5 | #include "GainputInputDeviceTouchImpl.h" 6 | #include "GainputTouchInfo.h" 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace gainput 13 | { 14 | 15 | class InputDeviceTouchImplIos : public InputDeviceTouchImpl 16 | { 17 | public: 18 | InputDeviceTouchImplIos(InputManager& manager, InputDevice& device, InputState& state, InputState& previousState) : 19 | manager_(manager), 20 | device_(device), 21 | state_(&state), 22 | previousState_(&previousState), 23 | nextState_(manager.GetAllocator(), TouchPointCount*TouchDataElems), 24 | delta_(0), 25 | touches_(manager.GetAllocator()), 26 | supportsPressure_(false) 27 | { 28 | } 29 | 30 | InputDevice::DeviceVariant GetVariant() const 31 | { 32 | return InputDevice::DV_STANDARD; 33 | } 34 | 35 | void Update(InputDeltaState* delta) 36 | { 37 | delta_ = delta; 38 | *state_ = nextState_; 39 | } 40 | 41 | InputDevice::DeviceState GetState() const { return InputDevice::DS_OK; } 42 | 43 | bool SupportsPressure() const 44 | { 45 | return supportsPressure_; 46 | } 47 | 48 | void SetSupportsPressure(bool supports) 49 | { 50 | supportsPressure_ = supports; 51 | } 52 | 53 | void HandleTouch(void* id, float x, float y, float z = 0.f) 54 | { 55 | GAINPUT_ASSERT(state_); 56 | GAINPUT_ASSERT(previousState_); 57 | 58 | int touchIdx = -1; 59 | for (unsigned i = 0; i < touches_.size(); ++i) 60 | { 61 | if (touches_[i] == static_cast(id)) 62 | { 63 | touchIdx = i; 64 | break; 65 | } 66 | } 67 | 68 | if (touchIdx == -1) 69 | { 70 | for (unsigned i = 0; i < touches_.size(); ++i) 71 | { 72 | if (touches_[i] == 0) 73 | { 74 | touches_[i] = static_cast(id); 75 | touchIdx = i; 76 | break; 77 | } 78 | } 79 | } 80 | 81 | if (touchIdx == -1) 82 | { 83 | touchIdx = static_cast(touches_.size()); 84 | touches_.push_back(static_cast(id)); 85 | } 86 | 87 | HandleBool(gainput::Touch0Down + touchIdx*4, true); 88 | HandleFloat(gainput::Touch0X + touchIdx*4, x); 89 | HandleFloat(gainput::Touch0Y + touchIdx*4, y); 90 | HandleFloat(gainput::Touch0Pressure + touchIdx*4, z); 91 | } 92 | 93 | void HandleTouchEnd(void* id, float x, float y, float z = 0.f) 94 | { 95 | GAINPUT_ASSERT(state_); 96 | GAINPUT_ASSERT(previousState_); 97 | 98 | int touchIdx = -1; 99 | for (unsigned i = 0; i < touches_.size(); ++i) 100 | { 101 | if (touches_[i] == static_cast(id)) 102 | { 103 | touchIdx = i; 104 | break; 105 | } 106 | } 107 | 108 | GAINPUT_ASSERT(touchIdx != -1); 109 | if (touchIdx == -1) 110 | { 111 | return; 112 | } 113 | 114 | touches_[touchIdx] = 0; 115 | 116 | HandleBool(gainput::Touch0Down + touchIdx*4, false); 117 | HandleFloat(gainput::Touch0X + touchIdx*4, x); 118 | HandleFloat(gainput::Touch0Y + touchIdx*4, y); 119 | HandleFloat(gainput::Touch0Pressure + touchIdx*4, z); 120 | } 121 | 122 | private: 123 | InputManager& manager_; 124 | InputDevice& device_; 125 | InputState* state_; 126 | InputState* previousState_; 127 | InputState nextState_; 128 | InputDeltaState* delta_; 129 | 130 | typedef gainput::Array< void* > TouchList; 131 | TouchList touches_; 132 | 133 | bool supportsPressure_; 134 | 135 | void HandleBool(DeviceButtonId buttonId, bool value) 136 | { 137 | manager_.EnqueueConcurrentChange(device_, nextState_, delta_, buttonId, value); 138 | } 139 | 140 | void HandleFloat(DeviceButtonId buttonId, float value) 141 | { 142 | manager_.EnqueueConcurrentChange(device_, nextState_, delta_, buttonId, value); 143 | } 144 | }; 145 | 146 | } 147 | 148 | #endif 149 | 150 | -------------------------------------------------------------------------------- /lib/source/gainput/touch/GainputInputDeviceTouchNull.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTINPUTDEVICETOUCHNULL_H_ 3 | #define GAINPUTINPUTDEVICETOUCHNULL_H_ 4 | 5 | namespace gainput 6 | { 7 | 8 | class InputDeviceTouchImplNull : public InputDeviceTouchImpl 9 | { 10 | public: 11 | InputDeviceTouchImplNull(InputManager& manager, InputDevice& device) 12 | { 13 | } 14 | 15 | InputDevice::DeviceVariant GetVariant() const 16 | { 17 | return InputDevice::DV_NULL; 18 | } 19 | 20 | void Update(InputDeltaState* /*delta*/) 21 | { 22 | } 23 | 24 | InputDevice::DeviceState GetState() const { return InputDevice::DS_OK; } 25 | }; 26 | 27 | } 28 | 29 | #endif 30 | 31 | -------------------------------------------------------------------------------- /lib/source/gainput/touch/GainputTouchInfo.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef GAINPUTTOUCHINFO_H_ 3 | #define GAINPUTTOUCHINFO_H_ 4 | 5 | namespace gainput 6 | { 7 | 8 | namespace 9 | { 10 | struct DeviceButtonInfo 11 | { 12 | ButtonType type; 13 | const char* name; 14 | }; 15 | 16 | DeviceButtonInfo const deviceButtonInfos[] = 17 | { 18 | { BT_BOOL, "touch_0_down" }, 19 | { BT_FLOAT, "touch_0_x" }, 20 | { BT_FLOAT, "touch_0_y" }, 21 | { BT_FLOAT, "touch_0_pressure" }, 22 | { BT_BOOL, "touch_1_down" }, 23 | { BT_FLOAT, "touch_1_x" }, 24 | { BT_FLOAT, "touch_1_y" }, 25 | { BT_FLOAT, "touch_1_pressure" }, 26 | { BT_BOOL, "touch_2_down" }, 27 | { BT_FLOAT, "touch_2_x" }, 28 | { BT_FLOAT, "touch_2_y" }, 29 | { BT_FLOAT, "touch_2_pressure" }, 30 | { BT_BOOL, "touch_3_down" }, 31 | { BT_FLOAT, "touch_3_x" }, 32 | { BT_FLOAT, "touch_3_y" }, 33 | { BT_FLOAT, "touch_3_pressure" }, 34 | { BT_BOOL, "touch_4_down" }, 35 | { BT_FLOAT, "touch_4_x" }, 36 | { BT_FLOAT, "touch_4_y" }, 37 | { BT_FLOAT, "touch_4_pressure" }, 38 | { BT_BOOL, "touch_5_down" }, 39 | { BT_FLOAT, "touch_5_x" }, 40 | { BT_FLOAT, "touch_5_y" }, 41 | { BT_FLOAT, "touch_5_pressure" }, 42 | { BT_BOOL, "touch_6_down" }, 43 | { BT_FLOAT, "touch_6_x" }, 44 | { BT_FLOAT, "touch_6_y" }, 45 | { BT_FLOAT, "touch_6_pressure" }, 46 | { BT_BOOL, "touch_7_down" }, 47 | { BT_FLOAT, "touch_7_x" }, 48 | { BT_FLOAT, "touch_7_y" }, 49 | { BT_FLOAT, "touch_7_pressure" } 50 | }; 51 | } 52 | 53 | const unsigned TouchPointCount = 8; 54 | const unsigned TouchDataElems = 4; 55 | 56 | } 57 | 58 | #endif 59 | 60 | -------------------------------------------------------------------------------- /samples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | find_package(X11) 3 | 4 | if(!ANDROID) 5 | find_package(OpenGL) 6 | endif(!ANDROID) 7 | 8 | if(APPLE AND NOT IOS) 9 | find_library(APPKIT AppKit) 10 | else() 11 | set(APPKIT "") 12 | endif() 13 | 14 | add_subdirectory(basic) 15 | add_subdirectory(dynamic) 16 | add_subdirectory(gesture) 17 | add_subdirectory(listener) 18 | add_subdirectory(recording) 19 | add_subdirectory(sync) 20 | 21 | -------------------------------------------------------------------------------- /samples/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | 18 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /samples/android/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-17 15 | -------------------------------------------------------------------------------- /samples/android/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | GainputSample 4 | 5 | -------------------------------------------------------------------------------- /samples/basic/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | project(basicsample) 3 | 4 | include_directories(../../lib/include/) 5 | 6 | file(GLOB_RECURSE sources *.cpp) 7 | 8 | if(APPLE) 9 | file(GLOB_RECURSE mmsources *.mm) 10 | endif() 11 | 12 | if(ANDROID) 13 | add_library(basicsample SHARED ${sources}) 14 | elseif(APPLE AND IOS) 15 | set(imagessources 16 | "${CMAKE_CURRENT_LIST_DIR}/../../extern/ios/Launch Screen.storyboard" 17 | ) 18 | add_executable(basicsample "MACOSX_BUNDLE" ${sources} ${mmsources} ${imagessources}) 19 | set_target_properties( basicsample PROPERTIES 20 | XCODE_ATTRIBUTE_INFOPLIST_FILE "${CMAKE_CURRENT_LIST_DIR}/../../extern/ios/Info.plist" 21 | XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer" 22 | ) 23 | target_link_libraries(basicsample ${UIKIT} ${QUARTZCORE}) 24 | else() 25 | add_executable(basicsample WIN32 ${sources} ${mmsources}) 26 | endif() 27 | 28 | target_link_libraries(basicsample gainputstatic) 29 | 30 | if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") 31 | target_link_libraries(basicsample X11 GL rt) 32 | elseif(WIN32) 33 | target_link_libraries(basicsample ${XINPUT} ws2_32) 34 | elseif(APPLE) 35 | target_link_libraries(basicsample ${FOUNDATION} ${IOKIT} ${APPKIT} ${GAME_CONTROLLER}) 36 | endif() 37 | 38 | -------------------------------------------------------------------------------- /samples/basic/basicsample_android.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #if defined(GAINPUT_PLATFORM_ANDROID) 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "gainput", __VA_ARGS__)) 17 | #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "gainput", __VA_ARGS__)) 18 | 19 | 20 | // Define your user buttons 21 | enum Button 22 | { 23 | ButtonMenu, 24 | ButtonConfirm 25 | }; 26 | 27 | 28 | static bool doExit = false; 29 | 30 | static int32_t MyHandleInput(struct android_app* app, AInputEvent* event) 31 | { 32 | // Forward input events to Gainput 33 | gainput::InputManager* inputManager = (gainput::InputManager*)app->userData; 34 | static bool resSet = false; 35 | if (!resSet) 36 | { 37 | inputManager->SetDisplaySize(ANativeWindow_getWidth(app->window), ANativeWindow_getHeight(app->window)); 38 | resSet = true; 39 | } 40 | return inputManager->HandleInput(event); 41 | } 42 | 43 | static void MyHandleCmd(struct android_app* app, int32_t cmd) 44 | { 45 | switch (cmd) 46 | { 47 | case APP_CMD_SAVE_STATE: 48 | break; 49 | case APP_CMD_INIT_WINDOW: 50 | break; 51 | case APP_CMD_TERM_WINDOW: 52 | doExit = true; 53 | break; 54 | case APP_CMD_LOST_FOCUS: 55 | doExit = true; 56 | break; 57 | case APP_CMD_GAINED_FOCUS: 58 | // bring back a certain functionality, like monitoring the accelerometer 59 | break; 60 | } 61 | } 62 | 63 | void android_main(struct android_app* state) 64 | { 65 | app_dummy(); 66 | 67 | // Set up Gainput 68 | gainput::InputManager manager; 69 | manager.CreateDevice(); 70 | manager.CreateDevice(); 71 | manager.CreateDevice(); 72 | 73 | // Make sure the app frowards input events to Gainput 74 | state->userData = &manager; 75 | state->onInputEvent = &MyHandleInput; 76 | state->onAppCmd = &MyHandleCmd; 77 | 78 | while (!doExit) 79 | { 80 | // Update Gainput 81 | manager.Update(); 82 | 83 | int ident; 84 | int events; 85 | struct android_poll_source* source; 86 | 87 | while (!doExit && (ident=ALooper_pollAll(0, NULL, &events, (void**)&source)) >= 0) 88 | { 89 | if (source != NULL) 90 | { 91 | source->process(state, source); 92 | } 93 | 94 | if (state->destroyRequested != 0) 95 | { 96 | doExit = true; 97 | } 98 | } 99 | } 100 | 101 | ANativeActivity_finish(state->activity); 102 | } 103 | 104 | 105 | #endif 106 | 107 | -------------------------------------------------------------------------------- /samples/basic/basicsample_android_generic.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #if defined(GAINPUT_PLATFORM_ANDROID) 5 | 6 | #include 7 | #include 8 | 9 | #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "gainput", __VA_ARGS__)) 10 | 11 | // Define your user buttons 12 | enum Button 13 | { 14 | ButtonMenu, 15 | ButtonConfirm, 16 | MouseX, 17 | MouseY 18 | }; 19 | 20 | gainput::InputManager* manager; 21 | gainput::InputMap* map; 22 | gainput::DeviceId mouseId; 23 | gainput::DeviceId keyboardId; 24 | gainput::DeviceId padId; 25 | gainput::DeviceId touchId; 26 | 27 | 28 | extern "C" { 29 | JNIEXPORT void JNICALL 30 | Java_com_example_gainput_gainput_BasicActivity_nativeOnCreate(JNIEnv * /*env*/, jobject /*thiz*/) 31 | { 32 | manager = new gainput::InputManager; 33 | mouseId = manager->CreateDevice(); 34 | keyboardId = manager->CreateDevice(); 35 | padId = manager->CreateDevice(); 36 | touchId = manager->CreateDevice(); 37 | 38 | map = new gainput::InputMap(*manager); 39 | map->MapBool(ButtonMenu, keyboardId, gainput::KeyBack); 40 | map->MapBool(ButtonConfirm, mouseId, gainput::MouseButtonLeft); 41 | map->MapBool(ButtonConfirm, padId, gainput::PadButtonA); 42 | map->MapBool(ButtonConfirm, touchId, gainput::Touch0Down); 43 | 44 | map->MapFloat(MouseX, mouseId, gainput::MouseAxisX); 45 | map->MapFloat(MouseY, mouseId, gainput::MouseAxisY); 46 | map->MapFloat(MouseX, touchId, gainput::Touch0X); 47 | map->MapFloat(MouseY, touchId, gainput::Touch0Y); 48 | } 49 | 50 | JNIEXPORT void JNICALL 51 | Java_com_example_gainput_gainput_BasicActivity_nativeOnUpdate(JNIEnv * /*env*/, jobject /*thiz*/) 52 | { 53 | manager->Update(); 54 | 55 | if (map->GetBoolWasDown(ButtonMenu)) 56 | { 57 | LOGI("Open Menu!!"); 58 | } 59 | if (map->GetBoolWasDown(ButtonConfirm)) 60 | { 61 | LOGI("Confirmed!!"); 62 | } 63 | if (map->GetBool(ButtonConfirm)) 64 | { 65 | LOGI("LM down"); 66 | } 67 | 68 | if (map->GetFloatDelta(MouseX) != 0.0f || map->GetFloatDelta(MouseY) != 0.0f) 69 | { 70 | LOGI("Mouse: %f, %f", map->GetFloat(MouseX), map->GetFloat(MouseY)); 71 | } 72 | } 73 | 74 | } 75 | 76 | #endif 77 | 78 | -------------------------------------------------------------------------------- /samples/basic/basicsample_ios.mm: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #if defined(GAINPUT_PLATFORM_IOS) 5 | #include 6 | 7 | #import 8 | 9 | #include 10 | 11 | 12 | // Define your user buttons 13 | enum Button 14 | { 15 | ButtonMenu, 16 | ButtonConfirm, 17 | MouseX, 18 | MouseY 19 | }; 20 | 21 | gainput::InputManager* manager; 22 | gainput::InputMap* map; 23 | gainput::DeviceId mouseId; 24 | gainput::DeviceId keyboardId; 25 | gainput::DeviceId padId; 26 | gainput::DeviceId touchId; 27 | 28 | @interface AppDelegate : UIResponder 29 | @property (strong, nonatomic) UIWindow *window; 30 | @end 31 | 32 | @implementation AppDelegate 33 | CADisplayLink* displayLink; 34 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 35 | manager = new gainput::InputManager; 36 | mouseId = manager->CreateDevice(); 37 | keyboardId = manager->CreateDevice(); 38 | padId = manager->CreateDevice(); 39 | touchId = manager->CreateDevice(); 40 | 41 | map = new gainput::InputMap(*manager); 42 | map->MapBool(ButtonMenu, keyboardId, gainput::KeyEscape); 43 | map->MapBool(ButtonConfirm, mouseId, gainput::MouseButtonLeft); 44 | map->MapBool(ButtonConfirm, padId, gainput::PadButtonA); 45 | map->MapBool(ButtonConfirm, touchId, gainput::Touch0Down); 46 | 47 | map->MapFloat(MouseX, mouseId, gainput::MouseAxisX); 48 | map->MapFloat(MouseY, mouseId, gainput::MouseAxisY); 49 | map->MapFloat(MouseX, touchId, gainput::Touch0X); 50 | map->MapFloat(MouseY, touchId, gainput::Touch0Y); 51 | 52 | 53 | CGRect bounds = [[UIScreen mainScreen] bounds]; 54 | self.window = [[[UIWindow alloc] init] autorelease]; 55 | self.window.rootViewController = [[[UIViewController alloc] init] autorelease]; 56 | self.window.backgroundColor = [UIColor blueColor]; 57 | [self.window makeKeyAndVisible]; 58 | [application setIdleTimerDisabled:TRUE]; 59 | 60 | UIView* gainputView = [[[GainputView alloc] initWithFrame:bounds inputManager:*manager] autorelease]; 61 | self.window.rootViewController.view = gainputView; 62 | 63 | displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)]; 64 | NSAssert(displayLink, @"Failed to create display link."); 65 | [displayLink setFrameInterval: 1]; 66 | [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 67 | return YES; 68 | } 69 | 70 | - (void)update 71 | { 72 | manager->Update(); 73 | 74 | // Check button states 75 | if (map->GetBoolWasDown(ButtonConfirm)) 76 | { 77 | gainput::InputDevicePad* pad = static_cast(manager->GetDevice(padId)); 78 | pad->Vibrate(1.0f, 0.0f); 79 | } 80 | if (map->GetBoolWasDown(ButtonMenu)) 81 | { 82 | gainput::InputDevicePad* pad = static_cast(manager->GetDevice(padId)); 83 | pad->Vibrate(0.0f, 0.0f); 84 | } 85 | 86 | if (map->GetBoolWasDown(ButtonMenu)) 87 | { 88 | std::cout << "Open Menu!!" << std::endl; 89 | } 90 | if (map->GetBoolWasDown(ButtonConfirm)) 91 | { 92 | std::cout << "Confirmed!!" << std::endl; 93 | } 94 | if (map->GetBool(ButtonConfirm)) 95 | { 96 | std::cout << "LM down" << std::endl; 97 | } 98 | 99 | if (map->GetFloatDelta(MouseX) != 0.0f || map->GetFloatDelta(MouseY) != 0.0f) 100 | { 101 | std::cout << "Mouse:" << map->GetFloat(MouseX) << ", " << map->GetFloat(MouseY) << std::endl; 102 | } 103 | } 104 | @end 105 | 106 | int main(int argc, char * argv[]) 107 | { 108 | @autoreleasepool 109 | { 110 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 111 | } 112 | } 113 | #endif 114 | 115 | -------------------------------------------------------------------------------- /samples/basic/basicsample_linux.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #if defined(GAINPUT_PLATFORM_LINUX) 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | // Define your user buttons 12 | enum Button 13 | { 14 | ButtonMenu, 15 | ButtonConfirm, 16 | MouseX, 17 | MouseY 18 | }; 19 | 20 | 21 | const char* windowName = "Gainput basic sample"; 22 | const int width = 800; 23 | const int height = 600; 24 | 25 | 26 | int main(int argc, char** argv) 27 | { 28 | static int attributeListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER, /*In case single buffering is not supported*/ GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, 29 | None }; 30 | 31 | Display* xDisplay = XOpenDisplay(0); 32 | if (xDisplay == 0) 33 | { 34 | std::cerr << "Cannot connect to X server." << std::endl; 35 | return -1; 36 | } 37 | 38 | Window root = DefaultRootWindow(xDisplay); 39 | 40 | XVisualInfo* vi = glXChooseVisual(xDisplay, DefaultScreen(xDisplay), attributeListDbl); 41 | assert(vi); 42 | 43 | GLXContext context = glXCreateContext(xDisplay, vi, 0, GL_TRUE); 44 | 45 | Colormap cmap = XCreateColormap(xDisplay, root, vi->visual, AllocNone); 46 | 47 | XSetWindowAttributes swa; 48 | swa.colormap = cmap; 49 | swa.event_mask = ExposureMask 50 | | KeyPressMask | KeyReleaseMask 51 | | PointerMotionMask | ButtonPressMask | ButtonReleaseMask; 52 | 53 | Window xWindow = XCreateWindow( 54 | xDisplay, root, 55 | 0, 0, width, height, 0, 56 | CopyFromParent, InputOutput, 57 | CopyFromParent, CWEventMask, 58 | &swa 59 | ); 60 | 61 | glXMakeCurrent(xDisplay, xWindow, context); 62 | 63 | XSetWindowAttributes xattr; 64 | xattr.override_redirect = False; 65 | XChangeWindowAttributes(xDisplay, xWindow, CWOverrideRedirect, &xattr); 66 | 67 | XMapWindow(xDisplay, xWindow); 68 | XStoreName(xDisplay, xWindow, windowName); 69 | 70 | // Setup Gainput 71 | gainput::InputManager manager; 72 | const gainput::DeviceId mouseId = manager.CreateDevice(); 73 | const gainput::DeviceId keyboardId = manager.CreateDevice(); 74 | const gainput::DeviceId padId = manager.CreateDevice(); 75 | 76 | gainput::InputMap map(manager); 77 | map.MapBool(ButtonMenu, keyboardId, gainput::KeyEscape); 78 | map.MapBool(ButtonConfirm, mouseId, gainput::MouseButtonLeft); 79 | map.MapFloat(MouseX, mouseId, gainput::MouseAxisX); 80 | map.MapFloat(MouseY, mouseId, gainput::MouseAxisY); 81 | map.MapBool(ButtonConfirm, padId, gainput::PadButtonA); 82 | 83 | manager.SetDisplaySize(width, height); 84 | 85 | for (;;) 86 | { 87 | // Update Gainput 88 | manager.Update(); 89 | 90 | XEvent event; 91 | while (XPending(xDisplay)) 92 | { 93 | XNextEvent(xDisplay, &event); 94 | manager.HandleEvent(event); 95 | } 96 | 97 | // Check button states 98 | if (map.GetBoolWasDown(ButtonMenu)) 99 | { 100 | std::cout << "Open menu!!" << std::endl; 101 | } 102 | if (map.GetBoolWasDown(ButtonConfirm)) 103 | { 104 | std::cout << "Confirmed!!" << std::endl; 105 | } 106 | 107 | if (map.GetFloatDelta(MouseX) != 0.0f || map.GetFloatDelta(MouseY) != 0.0f) 108 | { 109 | std::cout << "Mouse: " << map.GetFloat(MouseX) << ", " << map.GetFloat(MouseY) << std::endl; 110 | } 111 | } 112 | 113 | XDestroyWindow(xDisplay, xWindow); 114 | XCloseDisplay(xDisplay); 115 | 116 | return 0; 117 | } 118 | #endif 119 | 120 | -------------------------------------------------------------------------------- /samples/basic/basicsample_mac.mm: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #if defined(GAINPUT_PLATFORM_MAC) 5 | #include 6 | 7 | #import 8 | 9 | // Define your user buttons 10 | enum Button 11 | { 12 | ButtonMenu, 13 | ButtonConfirm, 14 | MouseX, 15 | MouseY 16 | }; 17 | 18 | 19 | const char* windowName = "Gainput basic sample"; 20 | const int width = 800; 21 | const int height = 600; 22 | 23 | gainput::InputManager* manager; 24 | gainput::InputMap* map; 25 | gainput::DeviceId mouseId; 26 | gainput::DeviceId keyboardId; 27 | gainput::DeviceId padId; 28 | 29 | @interface Updater : NSObject 30 | @end 31 | 32 | @implementation Updater 33 | - (void)update:(NSTimer *)theTimer 34 | { 35 | manager->Update(); 36 | 37 | // Check button states 38 | if (map->GetBoolWasDown(ButtonConfirm)) 39 | { 40 | gainput::InputDevicePad* pad = static_cast(manager->GetDevice(padId)); 41 | pad->Vibrate(1.0f, 0.0f); 42 | } 43 | if (map->GetBoolWasDown(ButtonMenu)) 44 | { 45 | gainput::InputDevicePad* pad = static_cast(manager->GetDevice(padId)); 46 | pad->Vibrate(0.0f, 0.0f); 47 | } 48 | 49 | if (map->GetBoolWasDown(ButtonMenu)) 50 | { 51 | std::cout << "Open Menu!!" << std::endl; 52 | } 53 | if (map->GetBoolWasDown(ButtonConfirm)) 54 | { 55 | std::cout << "Confirmed!!" << std::endl; 56 | } 57 | if (map->GetBool(ButtonConfirm)) 58 | { 59 | std::cout << "LM down" << std::endl; 60 | } 61 | 62 | if (map->GetFloatDelta(MouseX) != 0.0f || map->GetFloatDelta(MouseY) != 0.0f) 63 | { 64 | std::cout << "Mouse:" << map->GetFloat(MouseX) << ", " << map->GetFloat(MouseY) << std::endl; 65 | } 66 | } 67 | @end 68 | 69 | int main(int argc, char** argv) 70 | { 71 | [NSApplication sharedApplication]; 72 | [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; 73 | id window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, width, height) 74 | styleMask:NSTitledWindowMask|NSClosableWindowMask backing:NSBackingStoreBuffered defer:NO]; 75 | [window cascadeTopLeftFromPoint:NSMakePoint(20,20)]; 76 | [window setTitle: @"Gainput Basic Sample"]; 77 | [window makeKeyAndOrderFront:nil]; 78 | 79 | manager = new gainput::InputManager; 80 | manager->SetDisplaySize(width, height); 81 | mouseId = manager->CreateDevice(); 82 | keyboardId = manager->CreateDevice(); 83 | padId = manager->CreateDevice(); 84 | 85 | map = new gainput::InputMap(*manager); 86 | map->MapBool(ButtonMenu, keyboardId, gainput::KeyEscape); 87 | map->MapBool(ButtonConfirm, mouseId, gainput::MouseButtonLeft); 88 | map->MapFloat(MouseX, mouseId, gainput::MouseAxisX); 89 | map->MapFloat(MouseY, mouseId, gainput::MouseAxisY); 90 | map->MapBool(ButtonConfirm, padId, gainput::PadButtonA); 91 | 92 | Updater* updater = [[Updater alloc] init]; 93 | 94 | [NSTimer scheduledTimerWithTimeInterval:0.016 95 | target:updater 96 | selector:@selector(update:) 97 | userInfo:nil 98 | repeats:YES]; 99 | 100 | // [NSApp activateIgnoringOtherApps:YES]; 101 | [NSApp run]; 102 | 103 | return 0; 104 | } 105 | #endif 106 | 107 | -------------------------------------------------------------------------------- /samples/basic/basicsample_win.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #if defined(GAINPUT_PLATFORM_WIN) 5 | 6 | #define WIN32_LEAN_AND_MEAN 7 | #define NOMINMAX 8 | #include 9 | 10 | #include 11 | #define LOG(...) {char buf[256]; sprintf(buf, __VA_ARGS__); OutputDebugStringA(buf); } 12 | 13 | 14 | // Define your user buttons 15 | enum Button 16 | { 17 | ButtonMenu, 18 | ButtonConfirm, 19 | MouseX, 20 | MouseY 21 | }; 22 | 23 | 24 | static char szWindowClass[] = "win32app"; 25 | const char* windowName = "Gainput basic sample"; 26 | const int width = 800; 27 | const int height = 600; 28 | bool doExit = false; 29 | 30 | 31 | LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 32 | { 33 | PAINTSTRUCT ps; 34 | HDC hdc; 35 | char greeting[] = "Hello, World!"; 36 | 37 | switch (message) 38 | { 39 | case WM_PAINT: 40 | hdc = BeginPaint(hWnd, &ps); 41 | TextOut(hdc, 5, 5, greeting, strlen(greeting)); 42 | EndPaint(hWnd, &ps); 43 | break; 44 | case WM_DESTROY: 45 | PostQuitMessage(0); 46 | doExit = true; 47 | break; 48 | default: 49 | return DefWindowProc(hWnd, message, wParam, lParam); 50 | break; 51 | } 52 | 53 | return 0; 54 | } 55 | 56 | int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 57 | { 58 | WNDCLASSEX wcex; 59 | 60 | wcex.cbSize = sizeof(WNDCLASSEX); 61 | wcex.style = CS_HREDRAW | CS_VREDRAW; 62 | wcex.lpfnWndProc = WndProc; 63 | wcex.cbClsExtra = 0; 64 | wcex.cbWndExtra = 0; 65 | wcex.hInstance = hInstance; 66 | wcex.hIcon = 0; 67 | wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 68 | wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 69 | wcex.lpszMenuName = NULL; 70 | wcex.lpszClassName = szWindowClass; 71 | wcex.hIconSm = 0; 72 | 73 | if (!RegisterClassEx(&wcex)) 74 | { 75 | MessageBox(NULL, "Call to RegisterClassEx failed!", "Gainput basic sample", NULL); 76 | return 1; 77 | } 78 | 79 | HWND hWnd = CreateWindow( 80 | szWindowClass, 81 | windowName, 82 | WS_OVERLAPPEDWINDOW, 83 | CW_USEDEFAULT, CW_USEDEFAULT, 84 | width, height, 85 | NULL, 86 | NULL, 87 | hInstance, 88 | NULL 89 | ); 90 | 91 | if (!hWnd) 92 | { 93 | MessageBox(NULL, "Call to CreateWindow failed!", "Gainput basic sample", NULL); 94 | return 1; 95 | } 96 | 97 | ShowWindow(hWnd, nCmdShow); 98 | UpdateWindow(hWnd); 99 | 100 | // Setup Gainput 101 | gainput::InputManager manager; 102 | manager.SetDisplaySize(width, height); 103 | gainput::DeviceId mouseId = manager.CreateDevice(); 104 | gainput::DeviceId keyboardId = manager.CreateDevice(); 105 | gainput::DeviceId padId = manager.CreateDevice(); 106 | 107 | gainput::InputMap map(manager); 108 | map.MapBool(ButtonMenu, keyboardId, gainput::KeyEscape); 109 | map.MapBool(ButtonConfirm, mouseId, gainput::MouseButtonLeft); 110 | map.MapFloat(MouseX, mouseId, gainput::MouseAxisX); 111 | map.MapFloat(MouseY, mouseId, gainput::MouseAxisY); 112 | map.MapBool(ButtonConfirm, padId, gainput::PadButtonA); 113 | 114 | while (!doExit) 115 | { 116 | // Update Gainput 117 | manager.Update(); 118 | 119 | MSG msg; 120 | while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE)) 121 | { 122 | TranslateMessage(&msg); 123 | DispatchMessage(&msg); 124 | 125 | // Forward any input messages to Gainput 126 | manager.HandleMessage(msg); 127 | } 128 | 129 | // Check button states 130 | if (map.GetBoolWasDown(ButtonConfirm)) 131 | { 132 | gainput::InputDevicePad* pad = static_cast(manager.GetDevice(padId)); 133 | pad->Vibrate(1.0f, 0.0f); 134 | } 135 | if (map.GetBoolWasDown(ButtonMenu)) 136 | { 137 | gainput::InputDevicePad* pad = static_cast(manager.GetDevice(padId)); 138 | pad->Vibrate(0.0f, 0.0f); 139 | } 140 | 141 | if (map.GetBoolWasDown(ButtonMenu)) 142 | { 143 | LOG("Open Menu!!\n"); 144 | } 145 | if (map.GetBoolWasDown(ButtonConfirm)) 146 | { 147 | LOG("Confirmed!!\n"); 148 | } 149 | 150 | if (map.GetFloatDelta(MouseX) != 0.0f || map.GetFloatDelta(MouseY) != 0.0f) 151 | { 152 | LOG("Mouse: %f, %f\n", map.GetFloat(MouseX), map.GetFloat(MouseY)); 153 | } 154 | } 155 | 156 | return 0; 157 | } 158 | #endif 159 | 160 | -------------------------------------------------------------------------------- /samples/dynamic/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | project(dynamicsample) 3 | 4 | include_directories(../../lib/include/) 5 | include_directories(../samplefw/) 6 | 7 | file(GLOB_RECURSE sources *.cpp) 8 | file(GLOB_RECURSE sfwsources ../samplefw/*.cpp) 9 | 10 | if(ANDROID) 11 | add_library(dynamicsample SHARED ${sources} ${sfwsources}) 12 | else() 13 | add_executable(dynamicsample WIN32 ${sources} ${sfwsources}) 14 | endif() 15 | 16 | target_link_libraries(dynamicsample gainputstatic) 17 | 18 | if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") 19 | target_link_libraries(dynamicsample X11 GL rt) 20 | elseif(WIN32) 21 | target_link_libraries(dynamicsample ${XINPUT} ws2_32) 22 | elseif(APPLE) 23 | target_link_libraries(dynamicsample ${FOUNDATION} ${IOKIT} ${APPKIT}) 24 | endif() 25 | 26 | -------------------------------------------------------------------------------- /samples/gesture/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | project(gesturesample) 3 | 4 | include_directories(../../lib/include/) 5 | include_directories(../samplefw/) 6 | 7 | file(GLOB_RECURSE sources *.cpp) 8 | file(GLOB_RECURSE sfwsources ../samplefw/*.cpp) 9 | 10 | if(ANDROID) 11 | add_library(gesturesample SHARED ${sources} ${sfwsources}) 12 | else() 13 | add_executable(gesturesample WIN32 ${sources} ${sfwsources}) 14 | endif() 15 | 16 | target_link_libraries(gesturesample gainputstatic) 17 | 18 | if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") 19 | target_link_libraries(gesturesample X11 GL rt) 20 | elseif(WIN32) 21 | target_link_libraries(gesturesample ${XINPUT} ws2_32) 22 | elseif(APPLE) 23 | target_link_libraries(gesturesample ${FOUNDATION} ${IOKIT} ${APPKIT}) 24 | endif() 25 | 26 | -------------------------------------------------------------------------------- /samples/listener/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | project(listenersample) 3 | 4 | include_directories(../../lib/include/) 5 | include_directories(../samplefw/) 6 | 7 | file(GLOB_RECURSE sources *.cpp) 8 | file(GLOB_RECURSE sfwsources ../samplefw/*.cpp) 9 | 10 | if(ANDROID) 11 | add_library(listenersample SHARED ${sources} ${sfwsources}) 12 | else() 13 | add_executable(listenersample WIN32 ${sources} ${sfwsources}) 14 | endif() 15 | 16 | target_link_libraries(listenersample gainputstatic) 17 | 18 | if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") 19 | target_link_libraries(listenersample X11 GL rt) 20 | elseif(WIN32) 21 | target_link_libraries(listenersample ${XINPUT} ws2_32) 22 | elseif(APPLE) 23 | target_link_libraries(listenersample ${FOUNDATION} ${IOKIT} ${APPKIT}) 24 | endif() 25 | -------------------------------------------------------------------------------- /samples/recording/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | project(recordingsample) 3 | 4 | include_directories(../../lib/include/) 5 | include_directories(../samplefw/) 6 | 7 | file(GLOB_RECURSE sources *.cpp) 8 | file(GLOB_RECURSE sfwsources ../samplefw/*.cpp) 9 | 10 | if(ANDROID) 11 | add_library(recordingsample SHARED ${sources} ${sfwsources}) 12 | else() 13 | add_executable(recordingsample WIN32 ${sources} ${sfwsources}) 14 | endif() 15 | 16 | target_link_libraries(recordingsample gainputstatic) 17 | 18 | if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") 19 | target_link_libraries(recordingsample X11 GL rt) 20 | elseif(WIN32) 21 | target_link_libraries(recordingsample ${XINPUT} ws2_32) 22 | elseif(APPLE) 23 | target_link_libraries(recordingsample ${FOUNDATION} ${IOKIT} ${APPKIT}) 24 | endif() 25 | -------------------------------------------------------------------------------- /samples/samplefw/SampleFramework.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef SAMPLEFRAMEWORK_H_ 3 | #define SAMPLEFRAMEWORK_H_ 4 | 5 | 6 | void SfwOpenWindow(const char* title); 7 | void SfwCloseWindow(); 8 | void SfwUpdate(); 9 | bool SfwIsDone(); 10 | 11 | void SfwSetInputManager(gainput::InputManager* manager); 12 | 13 | int SfwGetWidth(); 14 | int SfwGetHeight(); 15 | 16 | 17 | #if defined(GAINPUT_PLATFORM_LINUX) 18 | #include 19 | 20 | Display* SfwGetXDisplay(); 21 | #include 22 | #define SFW_LOG(...) printf(__VA_ARGS__); 23 | 24 | #elif defined(GAINPUT_PLATFORM_WIN) 25 | 26 | #define WIN32_LEAN_AND_MEAN 27 | #define NOMINMAX 28 | #include 29 | 30 | HWND SfwGetHWnd(); 31 | 32 | #include 33 | #define SFW_LOG(...) { char buf[1024]; sprintf(buf, __VA_ARGS__); OutputDebugStringA(buf); } 34 | 35 | #elif defined(GAINPUT_PLATFORM_ANDROID) 36 | 37 | #include 38 | #define SFW_LOG(...) ((void)__android_log_print(ANDROID_LOG_INFO, "gainput", __VA_ARGS__)) 39 | 40 | #elif defined(GAINPUT_PLATFORM_MAC) 41 | 42 | #include 43 | #define SFW_LOG(...) printf(__VA_ARGS__); 44 | 45 | #endif 46 | 47 | #endif 48 | 49 | -------------------------------------------------------------------------------- /samples/sync/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | project(syncsample) 3 | 4 | include_directories(../../lib/include/) 5 | include_directories(../samplefw/) 6 | 7 | file(GLOB_RECURSE sources *.cpp) 8 | file(GLOB_RECURSE sfwsources ../samplefw/*.cpp) 9 | 10 | if(ANDROID) 11 | add_library(syncsample SHARED ${sources} ${sfwsources}) 12 | else() 13 | add_executable(syncsample WIN32 ${sources} ${sfwsources}) 14 | endif() 15 | 16 | target_link_libraries(syncsample gainputstatic) 17 | 18 | if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") 19 | target_link_libraries(syncsample X11 GL rt) 20 | elseif(WIN32) 21 | target_link_libraries(syncsample ${XINPUT} ws2_32) 22 | elseif(APPLE) 23 | target_link_libraries(syncsample ${FOUNDATION} ${IOKIT} ${APPKIT}) 24 | endif() 25 | -------------------------------------------------------------------------------- /samples/sync/syncsample.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include "../samplefw/SampleFramework.h" 5 | 6 | 7 | enum Button 8 | { 9 | ButtonClient, 10 | ButtonTest, 11 | ButtonMouseX, 12 | ButtonMouseLeft, 13 | ButtonCount 14 | }; 15 | 16 | class MyDeviceButtonListener : public gainput::InputListener 17 | { 18 | public: 19 | MyDeviceButtonListener(gainput::InputManager& manager) : manager(manager) { } 20 | 21 | bool OnDeviceButtonBool(gainput::DeviceId deviceId, gainput::DeviceButtonId deviceButton, bool oldValue, bool newValue) 22 | { 23 | const gainput::InputDevice* device = manager.GetDevice(deviceId); 24 | char buttonName[64]; 25 | device->GetButtonName(deviceButton, buttonName, 64); 26 | SFW_LOG("Device %d (%s%d) bool button (%d/%s) changed: %d -> %d\n", deviceId, device->GetTypeName(), device->GetIndex(), deviceButton, buttonName, oldValue, newValue); 27 | return true; 28 | } 29 | 30 | bool OnDeviceButtonFloat(gainput::DeviceId deviceId, gainput::DeviceButtonId deviceButton, float oldValue, float newValue) 31 | { 32 | const gainput::InputDevice* device = manager.GetDevice(deviceId); 33 | char buttonName[64]; 34 | device->GetButtonName(deviceButton, buttonName, 64); 35 | SFW_LOG("Device %d (%s%d) float button (%d/%s) changed: %f -> %f\n", deviceId, device->GetTypeName(), device->GetIndex(), deviceButton, buttonName, oldValue, newValue); 36 | return true; 37 | } 38 | 39 | private: 40 | gainput::InputManager& manager; 41 | }; 42 | 43 | void SampleMain() 44 | { 45 | SfwOpenWindow("Gainput: Sync sample"); 46 | 47 | gainput::InputManager manager; 48 | 49 | const gainput::DeviceId mouseId = manager.CreateDevice(); 50 | manager.CreateDevice(); 51 | const gainput::DeviceId keyboardId = manager.CreateDevice(); 52 | manager.CreateDevice(); 53 | 54 | #if defined(GAINPUT_PLATFORM_LINUX) || defined(GAINPUT_PLATFORM_WIN) 55 | manager.SetDisplaySize(SfwGetWidth(), SfwGetHeight()); 56 | #endif 57 | 58 | SfwSetInputManager(&manager); 59 | 60 | gainput::InputMap map(manager, "testmap"); 61 | map.MapBool(ButtonClient, keyboardId, gainput::KeyF1); 62 | map.MapFloat(ButtonMouseX, mouseId, gainput::MouseAxisX); 63 | map.MapFloat(ButtonMouseLeft, mouseId, gainput::MouseButtonLeft); 64 | 65 | MyDeviceButtonListener myDeviceButtonListener(manager); 66 | manager.AddListener(&myDeviceButtonListener); 67 | 68 | SFW_LOG("Press F1 to connect to localhost and start syncing.\n"); 69 | 70 | bool doExit = false; 71 | 72 | while (!SfwIsDone() & !doExit) 73 | { 74 | manager.Update(); 75 | 76 | #if defined(GAINPUT_PLATFORM_LINUX) 77 | XEvent event; 78 | while (XPending(SfwGetXDisplay())) 79 | { 80 | XNextEvent(SfwGetXDisplay(), &event); 81 | manager.HandleEvent(event); 82 | if (event.type == DestroyNotify || event.type == ClientMessage) 83 | { 84 | doExit = true; 85 | } 86 | } 87 | #elif defined(GAINPUT_PLATFORM_WIN) 88 | MSG msg; 89 | while (PeekMessage(&msg, SfwGetHWnd(), 0, 0, PM_REMOVE)) 90 | { 91 | TranslateMessage(&msg); 92 | DispatchMessage(&msg); 93 | manager.HandleMessage(msg); 94 | } 95 | #endif 96 | 97 | SfwUpdate(); 98 | 99 | if (map.GetBoolWasDown(ButtonClient)) 100 | { 101 | manager.ConnectForStateSync("127.0.0.1", 1211); 102 | manager.StartDeviceStateSync(mouseId); 103 | } 104 | 105 | if (map.GetBoolWasDown(ButtonMouseLeft)) 106 | { 107 | SFW_LOG("Mouse was down.\n"); 108 | } 109 | 110 | if (map.GetFloatDelta(ButtonMouseX) != 0.0f) 111 | { 112 | SFW_LOG("Mouse X: %f\n", map.GetFloat(ButtonMouseX)); 113 | } 114 | 115 | } 116 | 117 | SfwCloseWindow(); 118 | } 119 | 120 | 121 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | project(gainputtest) 3 | 4 | include_directories(../lib/include/) 5 | include_directories(../extern/catch/) 6 | 7 | file(GLOB_RECURSE sources *.cpp) 8 | 9 | if(CMAKE_COMPILER_IS_GNUCXX) 10 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") 11 | endif() 12 | 13 | if(ANDROID) 14 | add_library(gainputtest SHARED ${sources}) 15 | else() 16 | add_executable(gainputtest WIN32 ${sources}) 17 | endif() 18 | 19 | if(APPLE AND NOT IOS) 20 | find_library(APPKIT AppKit) 21 | else() 22 | set(APPKIT "") 23 | endif() 24 | 25 | target_link_libraries(gainputtest gainputstatic) 26 | 27 | if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") 28 | target_link_libraries(gainputtest X11 GL rt) 29 | elseif(WIN32) 30 | target_link_libraries(gainputtest ${XINPUT} ws2_32) 31 | elseif(APPLE) 32 | target_link_libraries(gainputtest ${FOUNDATION} ${IOKIT} ${APPKIT}) 33 | endif() 34 | 35 | if(MSVC) 36 | set_target_properties(gainputtest PROPERTIES LINK_FLAGS "/SUBSYSTEM:CONSOLE") 37 | endif(MSVC) 38 | -------------------------------------------------------------------------------- /test/test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #if defined(__ANDROID__) || defined(ANDROID) 3 | #include 4 | #define CATCH_CONFIG_RUNNER 5 | #include "catch.hpp" 6 | void android_main(struct android_app* stateMain) 7 | { 8 | app_dummy(); 9 | char* cmd[] = {"gainputtest"}; 10 | Catch::Session().run( 1, cmd ); 11 | } 12 | #else 13 | #define CATCH_CONFIG_MAIN 14 | #include "catch.hpp" 15 | #endif 16 | 17 | 18 | -------------------------------------------------------------------------------- /test/test_inputmanager.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "catch.hpp" 3 | 4 | #include 5 | 6 | using namespace gainput; 7 | 8 | TEST_CASE("InputManager/CreateDevice", "") 9 | { 10 | InputManager manager; 11 | 12 | const DeviceId deviceId = manager.CreateDevice(); 13 | REQUIRE(deviceId != InvalidDeviceId); 14 | 15 | InputDevice* device = manager.GetDevice(deviceId); 16 | REQUIRE(device); 17 | REQUIRE(device->GetType() == InputDevice::DT_KEYBOARD); 18 | REQUIRE(device->GetIndex() == 0); 19 | 20 | const DeviceId deviceId2 = manager.CreateDevice(); 21 | REQUIRE(deviceId2 != InvalidDeviceId); 22 | 23 | InputDevice* device2 = manager.GetDevice(deviceId2); 24 | REQUIRE(device2); 25 | REQUIRE(device2->GetType() == InputDevice::DT_MOUSE); 26 | REQUIRE(device2->GetIndex() == 0); 27 | 28 | InputDevicePad* device3 = manager.CreateAndGetDevice(); 29 | REQUIRE(device3); 30 | REQUIRE(device3->GetType() == InputDevice::DT_PAD); 31 | REQUIRE(device3->GetIndex() == 0); 32 | REQUIRE(device3->GetDeviceId() != InvalidDeviceId); 33 | } 34 | 35 | TEST_CASE("InputManager/FindDeviceId", "") 36 | { 37 | InputManager manager; 38 | const DeviceId deviceId = manager.CreateDevice(); 39 | const InputDevice* device = manager.GetDevice(deviceId); 40 | const DeviceId deviceId2 = manager.CreateDevice(); 41 | const InputDevice* device2 = manager.GetDevice(deviceId2); 42 | const DeviceId deviceId3 = manager.CreateDevice(); 43 | const InputDevice* device3 = manager.GetDevice(deviceId3); 44 | 45 | REQUIRE(manager.FindDeviceId(device->GetTypeName(), device->GetIndex()) == deviceId); 46 | REQUIRE(manager.FindDeviceId(device->GetType(), device->GetIndex()) == deviceId); 47 | 48 | REQUIRE(manager.FindDeviceId(device2->GetTypeName(), device2->GetIndex()) == deviceId2); 49 | REQUIRE(manager.FindDeviceId(device2->GetType(), device2->GetIndex()) == deviceId2); 50 | 51 | REQUIRE(manager.FindDeviceId(device3->GetTypeName(), device3->GetIndex()) == deviceId3); 52 | REQUIRE(manager.FindDeviceId(device3->GetType(), device3->GetIndex()) == deviceId3); 53 | } 54 | 55 | TEST_CASE("InputManager/GetDeviceCountByType", "") 56 | { 57 | InputManager manager; 58 | 59 | for (int type = InputDevice::DT_MOUSE; type < InputDevice::DT_COUNT; ++type) 60 | { 61 | REQUIRE(manager.GetDeviceCountByType(InputDevice::DeviceType(type)) == 0); 62 | } 63 | 64 | manager.CreateDevice(); 65 | manager.CreateDevice(); 66 | manager.CreateDevice(); 67 | 68 | REQUIRE(manager.GetDeviceCountByType(InputDevice::DT_KEYBOARD) == 1); 69 | REQUIRE(manager.GetDeviceCountByType(InputDevice::DT_MOUSE) == 1); 70 | REQUIRE(manager.GetDeviceCountByType(InputDevice::DT_PAD) == 1); 71 | REQUIRE(manager.GetDeviceCountByType(InputDevice::DT_TOUCH) == 0); 72 | } 73 | 74 | TEST_CASE("InputManager/GetAnyButtonDown", "") 75 | { 76 | InputManager manager; 77 | REQUIRE(manager.GetAnyButtonDown(0, 0) == 0); 78 | } 79 | 80 | -------------------------------------------------------------------------------- /test/test_inputrecording.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "catch.hpp" 3 | 4 | #include 5 | 6 | using namespace gainput; 7 | 8 | TEST_CASE("InputRecording/general", "") 9 | { 10 | InputRecording recording; 11 | 12 | REQUIRE(recording.GetDuration() == 0); 13 | REQUIRE(recording.GetSerializedSize() > 0); 14 | 15 | recording.AddChange(100, 0, 0, true); 16 | 17 | REQUIRE(recording.GetDuration() == 100); 18 | 19 | RecordedDeviceButtonChange change; 20 | 21 | REQUIRE(!recording.GetNextChange(50, change)); 22 | REQUIRE(recording.GetNextChange(100, change)); 23 | REQUIRE(change.time == 100); 24 | REQUIRE(change.deviceId == 0); 25 | REQUIRE(change.buttonId == 0); 26 | REQUIRE(change.b == true); 27 | 28 | REQUIRE(!recording.GetNextChange(1000, change)); 29 | 30 | recording.Reset(); 31 | recording.AddChange(150, 5, 102, 0.8f); 32 | 33 | REQUIRE(!recording.GetNextChange(50, change)); 34 | REQUIRE(recording.GetNextChange(101, change)); 35 | REQUIRE(recording.GetNextChange(160, change)); 36 | REQUIRE(change.time == 150); 37 | REQUIRE(change.deviceId == 5); 38 | REQUIRE(change.buttonId == 102); 39 | REQUIRE(change.f == 0.8f); 40 | REQUIRE(!recording.GetNextChange(1000, change)); 41 | 42 | recording.Reset(); 43 | recording.Clear(); 44 | 45 | REQUIRE(recording.GetDuration() == 0); 46 | REQUIRE(!recording.GetNextChange(10000, change)); 47 | } 48 | 49 | TEST_CASE("InputRecording/serialization", "") 50 | { 51 | InputManager manager; 52 | const DeviceId deviceId = manager.CreateDevice(); 53 | InputRecording recording; 54 | 55 | recording.AddChange(500, deviceId, MouseButtonLeft, true); 56 | recording.AddChange(600, deviceId, MouseButtonMiddle, false); 57 | recording.AddChange(700, deviceId, MouseAxisX, 0.2f); 58 | 59 | REQUIRE(recording.GetSerializedSize() > 0); 60 | 61 | void* serializedData = malloc(recording.GetSerializedSize()); 62 | recording.GetSerialized(manager, serializedData); 63 | 64 | InputRecording recording2(manager, serializedData, recording.GetSerializedSize()); 65 | 66 | free(serializedData); 67 | 68 | REQUIRE(recording.GetSerializedSize() == recording2.GetSerializedSize()); 69 | REQUIRE(recording.GetDuration() == recording2.GetDuration()); 70 | 71 | RecordedDeviceButtonChange change, change2; 72 | 73 | for (unsigned t = 500; t <= 700; t += 100) 74 | { 75 | REQUIRE(recording.GetNextChange(t, change)); 76 | REQUIRE(recording2.GetNextChange(t, change2)); 77 | REQUIRE(change.time == change2.time); 78 | REQUIRE(change.deviceId == change2.deviceId); 79 | REQUIRE(change.buttonId == change2.buttonId); 80 | if (t == 700) 81 | { 82 | REQUIRE(change.f == change2.f); 83 | } 84 | else 85 | { 86 | REQUIRE(change.b == change2.b); 87 | } 88 | } 89 | } 90 | 91 | TEST_CASE("InputPlayer", "") 92 | { 93 | InputManager manager; 94 | InputPlayer player(manager); 95 | 96 | REQUIRE(!player.GetRecording()); 97 | 98 | InputRecording recording;; 99 | player.SetRecording(&recording); 100 | 101 | REQUIRE(player.GetRecording() == &recording); 102 | 103 | REQUIRE(!player.IsPlaying()); 104 | player.Start(); 105 | REQUIRE(player.IsPlaying()); 106 | player.Stop(); 107 | REQUIRE(!player.IsPlaying()); 108 | } 109 | 110 | TEST_CASE("InputRecorder", "") 111 | { 112 | InputManager manager; 113 | 114 | InputRecorder recorder(manager); 115 | 116 | REQUIRE(!recorder.IsRecording()); 117 | recorder.Start(); 118 | REQUIRE(recorder.IsRecording()); 119 | recorder.Stop(); 120 | REQUIRE(!recorder.IsRecording()); 121 | 122 | REQUIRE(recorder.GetRecording()); 123 | 124 | REQUIRE(recorder.IsDeviceToRecord(0)); 125 | REQUIRE(recorder.IsDeviceToRecord(1)); 126 | REQUIRE(recorder.IsDeviceToRecord(2358349)); 127 | 128 | recorder.AddDeviceToRecord(0); 129 | REQUIRE(recorder.IsDeviceToRecord(0)); 130 | REQUIRE(!recorder.IsDeviceToRecord(1)); 131 | REQUIRE(!recorder.IsDeviceToRecord(2358349)); 132 | } 133 | 134 | -------------------------------------------------------------------------------- /test/test_inputstate.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "catch.hpp" 3 | 4 | #include 5 | 6 | using namespace gainput; 7 | 8 | const unsigned ButtonCount = 15; 9 | 10 | TEST_CASE("InputState", "") 11 | { 12 | InputState state(GetDefaultAllocator(), ButtonCount); 13 | InputState state2(GetDefaultAllocator(), ButtonCount); 14 | 15 | for (unsigned i = 0; i < ButtonCount; ++i) 16 | { 17 | REQUIRE(!state.GetBool(i)); 18 | REQUIRE(state.GetFloat(i) == 0.0f); 19 | } 20 | 21 | for (unsigned i = 0; i < ButtonCount; ++i) 22 | { 23 | const bool s = i & 1; 24 | state.Set(i, s); 25 | REQUIRE(state.GetBool(i) == s); 26 | } 27 | 28 | state2 = state; 29 | for (unsigned i = 0; i < ButtonCount; ++i) 30 | { 31 | REQUIRE(state2.GetBool(i) == state.GetBool(i)); 32 | } 33 | 34 | float s = 0.0f; 35 | for (unsigned i = 0; i < ButtonCount; ++i) 36 | { 37 | state.Set(i, s); 38 | REQUIRE(state.GetFloat(i) == s); 39 | s += float(i)*0.0354f; 40 | } 41 | 42 | state2 = state; 43 | for (unsigned i = 0; i < ButtonCount; ++i) 44 | { 45 | REQUIRE(state2.GetFloat(i) == state.GetFloat(i)); 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /tools/html5client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Gainput Javascript touch client 4 | 11 | 12 | 13 | 14 |
15 | 16 |

17 | Host:
18 | Port:
19 |

20 | 21 |

22 | Touch Device: 32 |

33 | 34 |

35 | 36 |

37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /tools/html5client/touch.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Gainput Javascript touch client 4 | 14 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | --------------------------------------------------------------------------------