h-raylib 5.1.1.0 → 5.1.2.0
raw patch · 109 files changed
+10105/−8256 lines, 109 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Raylib.Core: c'getMouseRay :: Ptr Vector2 -> Ptr Camera3D -> IO (Ptr Ray)
- Raylib.Core: c'getViewRay :: Ptr Vector2 -> Ptr Camera3D -> CFloat -> CFloat -> IO (Ptr Ray)
- Raylib.Core: getMouseRay :: Vector2 -> Camera3D -> IO Ray
- Raylib.Core: getViewRay :: Vector2 -> Camera3D -> Float -> Float -> IO Ray
- Raylib.Core.Textures: imageCopy :: Image -> IO Image
- Raylib.Types.Core: [filePathlist'capacity] :: FilePathList -> Integer
- Raylib.Types.Util.GUI: Icon220 :: GuiIconName
- Raylib.Types.Util.GUI: Icon221 :: GuiIconName
- Raylib.Types.Util.GUI: Icon222 :: GuiIconName
- Raylib.Util.Lenses: _filePathlist'capacity :: Lens' FilePathList Integer
+ Raylib.Core: c'getScreenToWorldRay :: Ptr Vector2 -> Ptr Camera3D -> IO (Ptr Ray)
+ Raylib.Core: c'getScreenToWorldRayEx :: Ptr Vector2 -> Ptr Camera3D -> CFloat -> CFloat -> IO (Ptr Ray)
+ Raylib.Core: c'setGamepadVibration :: CInt -> CFloat -> CFloat -> IO ()
+ Raylib.Core: getScreenToWorldRay :: Vector2 -> Camera3D -> IO Ray
+ Raylib.Core: getScreenToWorldRayEx :: Vector2 -> Camera3D -> Float -> Float -> IO Ray
+ Raylib.Core: setGamepadVibration :: Int -> Float -> Float -> IO ()
+ Raylib.Types.Core: [filePathList'capacity] :: FilePathList -> Integer
+ Raylib.Types.Util.GUI: IconHelpBox :: GuiIconName
+ Raylib.Types.Util.GUI: IconInfoBox :: GuiIconName
+ Raylib.Types.Util.GUI: IconWarning :: GuiIconName
+ Raylib.Util.Lenses: _filePathList'capacity :: Lens' FilePathList Integer
+ Raylib.Util.Math: vector2Refract :: Vector2 -> Vector2 -> Float -> Vector2
- Raylib.Core.Textures: updateTexture :: Texture -> Ptr () -> IO Texture
+ Raylib.Core.Textures: updateTexture :: Texture -> Ptr () -> IO ()
- Raylib.Core.Textures: updateTextureRec :: Texture -> Rectangle -> Ptr () -> IO Texture
+ Raylib.Core.Textures: updateTextureRec :: Texture -> Rectangle -> Ptr () -> IO ()
- Raylib.Types.Core.Models: unpackShaderUniformData :: ShaderUniformData -> IO (ShaderUniformDataType, Ptr ())
+ Raylib.Types.Core.Models: unpackShaderUniformData :: ShaderUniformData -> IO (ShaderUniformDataType, ForeignPtr ())
- Raylib.Types.Core.Models: unpackShaderUniformDataV :: ShaderUniformDataV -> IO (ShaderUniformDataType, Ptr (), Int)
+ Raylib.Types.Core.Models: unpackShaderUniformDataV :: ShaderUniformDataV -> IO (ShaderUniformDataType, ForeignPtr (), Int)
Files
- CHANGELOG.md +7/−0
- CONTRIBUTING.md +6/−5
- DOCUMENTATION.md +4/−0
- default.nix +15/−0
- examples/bunnymark/src/Main.hs +90/−95
- flake.nix +91/−0
- h-raylib.cabal +4/−2
- lib/rl_bindings.c +9/−4
- lib/rl_bindings.h +4/−2
- raygui/src/raygui.h +30/−32
- raylib/examples/core/core_3d_picking.c +1/−1
- raylib/examples/core/core_random_sequence.c +176/−0
- raylib/examples/models/models_bone_socket.c +177/−0
- raylib/examples/models/models_first_person_maze.c +0/−1
- raylib/examples/models/models_loading.c +1/−1
- raylib/examples/models/models_loading_vox.c +154/−82
- raylib/examples/models/models_mesh_picking.c +1/−1
- raylib/examples/models/rlights.h +170/−0
- raylib/examples/others/raylib_opengl_interop.c +2/−1
- raylib/examples/text/text_codepoints_loading.c +2/−3
- raylib/examples/text/text_draw_3d.c +1/−1
- raylib/examples/textures/textures_image_generation.c +1/−1
- raylib/src/config.h +1/−0
- raylib/src/external/cgltf.h +168/−62
- raylib/src/external/glfw/deps/vs2008/stdint.h +0/−247
- raylib/src/external/glfw/include/GLFW/glfw3.h +236/−112
- raylib/src/external/glfw/include/GLFW/glfw3native.h +63/−34
- raylib/src/external/glfw/src/cocoa_init.m +81/−77
- raylib/src/external/glfw/src/cocoa_joystick.h +0/−2
- raylib/src/external/glfw/src/cocoa_joystick.m +12/−5
- raylib/src/external/glfw/src/cocoa_monitor.m +21/−4
- raylib/src/external/glfw/src/cocoa_platform.h +2/−2
- raylib/src/external/glfw/src/cocoa_time.c +4/−2
- raylib/src/external/glfw/src/cocoa_window.m +50/−27
- raylib/src/external/glfw/src/context.c +2/−2
- raylib/src/external/glfw/src/egl_context.c +67/−40
- raylib/src/external/glfw/src/glx_context.c +5/−2
- raylib/src/external/glfw/src/init.c +16/−33
- raylib/src/external/glfw/src/input.c +13/−8
- raylib/src/external/glfw/src/internal.h +27/−34
- raylib/src/external/glfw/src/linux_joystick.c +10/−5
- raylib/src/external/glfw/src/linux_joystick.h +1/−2
- raylib/src/external/glfw/src/mappings.h +937/−1502
- raylib/src/external/glfw/src/monitor.c +4/−4
- raylib/src/external/glfw/src/nsgl_context.m +17/−9
- raylib/src/external/glfw/src/null_init.c +205/−74
- raylib/src/external/glfw/src/null_joystick.c +0/−2
- raylib/src/external/glfw/src/null_monitor.c +3/−4
- raylib/src/external/glfw/src/null_platform.h +125/−3
- raylib/src/external/glfw/src/null_window.c +78/−78
- raylib/src/external/glfw/src/osmesa_context.c +2/−5
- raylib/src/external/glfw/src/platform.c +28/−13
- raylib/src/external/glfw/src/platform.h +52/−3
- raylib/src/external/glfw/src/posix_module.c +4/−2
- raylib/src/external/glfw/src/posix_poll.c +4/−2
- raylib/src/external/glfw/src/posix_poll.h +0/−2
- raylib/src/external/glfw/src/posix_thread.c +4/−2
- raylib/src/external/glfw/src/posix_time.c +4/−2
- raylib/src/external/glfw/src/vulkan.c +0/−2
- raylib/src/external/glfw/src/wgl_context.c +22/−2
- raylib/src/external/glfw/src/win32_init.c +84/−79
- raylib/src/external/glfw/src/win32_joystick.c +11/−2
- raylib/src/external/glfw/src/win32_joystick.h +0/−2
- raylib/src/external/glfw/src/win32_module.c +4/−2
- raylib/src/external/glfw/src/win32_monitor.c +26/−4
- raylib/src/external/glfw/src/win32_platform.h +4/−1
- raylib/src/external/glfw/src/win32_thread.c +4/−2
- raylib/src/external/glfw/src/win32_thread.h +5/−0
- raylib/src/external/glfw/src/win32_time.c +3/−2
- raylib/src/external/glfw/src/win32_time.h +5/−0
- raylib/src/external/glfw/src/win32_window.c +167/−85
- raylib/src/external/glfw/src/window.c +26/−9
- raylib/src/external/glfw/src/wl_init.c +315/−104
- raylib/src/external/glfw/src/wl_monitor.c +18/−16
- raylib/src/external/glfw/src/wl_platform.h +194/−24
- raylib/src/external/glfw/src/wl_window.c +3307/−2887
- raylib/src/external/glfw/src/x11_init.c +86/−83
- raylib/src/external/glfw/src/x11_monitor.c +31/−6
- raylib/src/external/glfw/src/x11_platform.h +1/−1
- raylib/src/external/glfw/src/x11_window.c +39/−32
- raylib/src/external/glfw/src/xkb_unicode.c +3/−2
- raylib/src/external/vox_loader.h +17/−0
- raylib/src/platforms/rcore_android.c +6/−0
- raylib/src/platforms/rcore_desktop.c +31/−12
- raylib/src/platforms/rcore_desktop_sdl.c +47/−27
- raylib/src/platforms/rcore_drm.c +1727/−1934
- raylib/src/platforms/rcore_web.c +6/−0
- raylib/src/raudio.c +4/−4
- raylib/src/raylib.h +20/−17
- raylib/src/raymath.h +298/−4
- raylib/src/rcore.c +37/−24
- raylib/src/rglfw.c +4/−4
- raylib/src/rlgl.h +11/−3
- raylib/src/rmodels.c +47/−24
- raylib/src/rshapes.c +7/−7
- raylib/src/rtext.c +11/−11
- raylib/src/rtextures.c +27/−10
- raylib/src/utils.c +10/−4
- src/Raylib/Core.hs +33/−20
- src/Raylib/Core/Models.hs +8/−13
- src/Raylib/Core/Textures.hs +5/−9
- src/Raylib/Internal/Foreign.hs +39/−34
- src/Raylib/Types/Core.hs +5/−3
- src/Raylib/Types/Core/Models.hs +65/−46
- src/Raylib/Types/Core/Text.hs +2/−2
- src/Raylib/Types/Util/GUI.hs +9/−9
- src/Raylib/Types/Util/RLGL.hs +2/−2
- src/Raylib/Util/Math.hs +74/−44
- src/Raylib/Util/RLGL.hs +6/−3
CHANGELOG.md view
@@ -1,5 +1,12 @@ # h-raylib changelog +## Version 5.1.2.0+_9 April, 2024_++- Internal changes for performance+- Fixed a typo in `filePathList'capacity` (previously `filePathlist'capacity`)+- Fixed marshalling bugs with `FilePathList`+ ## Version 5.1.1.0 _22 February, 2024_
CONTRIBUTING.md view
@@ -30,16 +30,17 @@ Items which have been completed but not published to hackage. -- Implement automatic memory management for callbacks-- Move Raylib.Internal.Native functions into the modules where they are called- - Use Template Haskell to clean up boilerplate-- Split Raylib.Types into multiple modules-- Bind `raygui` \[[#34](https://github.com/Anut-py/h-raylib/issues/34)\]+(none) ## Published Items which have been published to hackage. +- Implement automatic memory management for callbacks (`5.1.1.0`)+- Move Raylib.Internal.Native functions into the modules where they are called (`5.1.1.0`)+ - Use Template Haskell to clean up boilerplate+- Split Raylib.Types into multiple modules (`5.1.1.0`)+- Bind `raygui` \[[#34](https://github.com/Anut-py/h-raylib/issues/34)\] (`5.1.1.0`) - Bind `raymath` (`4.6.0.1`) - Bind `rcamera` (`4.6.0.1`) - Bind `rlgl` (`4.5.3.2`)
DOCUMENTATION.md view
@@ -4,6 +4,10 @@ For regular users of the library, the Haddock documentation should be more than enough (although much of it is auto-generated, so make sure to create an issue if you find anything that seems wrong). The documentation included here is more useful for contributors or anyone who wants to learn about how h-raylib works internally. +## Versioning scheme++The first two numbers in the version track the underlying C raylib version. For example, `5.1.x.x` versions use raylib 5.1 under the hood. The third number represents breaking changes (renamed/deleted functions or modules). The last number represents non-breaking changes (new functions or modules, bug fixes, etc).+ ## Project structure h-raylib contains bindings for raylib.h, raymath.h, rcamera.h, rlgl.h, and raygui.h. The public modules' documentation can be found in Haddock, as mentioned above, and documentation for the private modules can be found in the source files.
+ default.nix view
@@ -0,0 +1,15 @@+{ mkDerivation, base, containers, exceptions, lens, template-haskell, text, bytestring+, lib, systemDeps, buildExamples, ...+}:+mkDerivation {+ pname = "h-raylib";+ version = "5.1.1.0";+ src = ./.;+ isLibrary = true;+ isExecutable = buildExamples;+ configureFlags = ["-fplatform-nixos"] ++ lib.optional buildExamples ["-fexamples"];+ libraryHaskellDepends = [ base containers exceptions lens template-haskell text bytestring ];+ librarySystemDepends = systemDeps;+ description = "Raylib bindings for Haskell";+ license = lib.licenses.asl20;+}
examples/bunnymark/src/Main.hs view
@@ -9,16 +9,16 @@ import Control.Monad (forM_, unless, void, when) import Foreign- ( Ptr,- Storable (alignment, peek, peekByteOff, poke, pokeByteOff, sizeOf),+ ( ForeignPtr,+ Ptr,+ Storable (alignment, peek, poke, sizeOf), advancePtr,- callocArray, free,- malloc,- nullPtr,+ mallocForeignPtrArray, peek, plusPtr, poke,+ withForeignPtr, ) import Foreign.C (CFloat, withCString) import Raylib.Core@@ -57,35 +57,35 @@ py :: !Float, sx :: !Float, sy :: !Float,- color :: !(Ptr Color) -- Store colors as pointers to avoid reallocating memory each time+ color :: !Color } deriving (Show, Eq) cfs :: Int cfs = sizeOf (0 :: CFloat) -nps :: Int-nps = sizeOf nullPtr+cls :: Int+cls = sizeOf (undefined :: Color) instance Storable Bunny where- alignment _ = min cfs nps- sizeOf _ = 4 * cfs + nps+ alignment _ = min cfs cls+ sizeOf _ = 4 * cfs + cls -- We do not peek/poke entire bunnies in this example, so the code below is never called -- (we advance the pointers using the `p'*` functions to directly access the fields) peek _p = do- _px <- realToFrac <$> (peekByteOff _p (0 * cfs) :: IO CFloat)- _py <- realToFrac <$> (peekByteOff _p (1 * cfs) :: IO CFloat)- _sx <- realToFrac <$> (peekByteOff _p (2 * cfs) :: IO CFloat)- _sy <- realToFrac <$> (peekByteOff _p (3 * cfs) :: IO CFloat)- _color <- peekByteOff _p (4 * cfs) :: IO (Ptr Color)+ _px <- realToFrac <$> peek (p'px _p)+ _py <- realToFrac <$> peek (p'py _p)+ _sx <- realToFrac <$> peek (p'sx _p)+ _sy <- realToFrac <$> peek (p'sy _p)+ _color <- peek (p'color _p) return $ Bunny {px = _px, py = _py, sx = _sx, sy = _sy, color = _color} poke _p (Bunny _px _py _sx _sy _color) = do- pokeByteOff _p (0 * cfs) (realToFrac _px :: CFloat)- pokeByteOff _p (1 * cfs) (realToFrac _py :: CFloat)- pokeByteOff _p (2 * cfs) (realToFrac _sx :: CFloat)- pokeByteOff _p (3 * cfs) (realToFrac _sy :: CFloat)- pokeByteOff _p (4 * cfs) _color+ poke (p'px _p) (realToFrac _px)+ poke (p'py _p) (realToFrac _py)+ poke (p'sx _p) (realToFrac _sx)+ poke (p'sy _p) (realToFrac _sy)+ poke (p'color _p) _color return () p'px :: Ptr Bunny -> Ptr CFloat@@ -100,14 +100,14 @@ p'sy :: Ptr Bunny -> Ptr CFloat p'sy = (`plusPtr` (3 * cfs)) -p'color :: Ptr Bunny -> Ptr (Ptr Color)+p'color :: Ptr Bunny -> Ptr Color p'color = (`plusPtr` (4 * cfs)) data AppState = AppState { texBunny :: !(Ptr Texture), halfTexWidth :: !CFloat, halfTexHeight :: !CFloat,- bunnies :: !(Ptr Bunny), -- Store the bunnies as a pointer because Haskell linked lists are extremely slow+ bunnies :: !(ForeignPtr Bunny), -- Store the bunnies as a pointer (C-style array) because Haskell linked lists are extremely slow bunniesCount :: !Int } deriving (Show, Eq)@@ -127,7 +127,7 @@ -- but the code below is faster as it doesn't have to load the entire structure into Haskell tWidth <- peek (p'texture'width texPtr) tHeight <- peek (p'texture'height texPtr)- bunniesPtr <- callocArray maxBunnies+ bunniesPtr <- mallocForeignPtrArray maxBunnies return ( AppState { texBunny = texPtr,@@ -140,80 +140,77 @@ mainLoop :: AppState -> IO AppState mainLoop state = do- screenWidth <- getScreenWidth- screenHeight <- getScreenHeight+ withForeignPtr (bunnies state) $ \bptr -> do+ screenWidth <- getScreenWidth+ screenHeight <- getScreenHeight - beginDrawing- clearBackground rayWhite- forM_- [0 .. (bunniesCount state - 1)]- ( \(!i) ->- do- -- Advancing the array pointer to get a pointer to a bunny- let bunny = advancePtr (bunnies state) i- -- Advancing the bunny pointer to access the fields- _px <- peek $ p'px bunny- _py <- peek $ p'py bunny- _color <- peek $ p'color bunny- c'drawTexture (texBunny state) (floor _px) (floor _py) _color- )- drawRectangle 0 0 screenWidth 40 black- drawText ("bunnies: " ++ show (bunniesCount state)) 120 10 20 green- drawText ("batched draw calls: " ++ show (1 + (bunniesCount state `div` 8192))) 320 10 20 maroon- drawFPS 10 10- endDrawing+ beginDrawing+ clearBackground rayWhite+ forM_+ [0 .. (bunniesCount state - 1)]+ ( \(!i) ->+ do+ -- Advancing the array pointer to get a pointer to a bunny+ let bunny = advancePtr bptr i+ -- Advancing the bunny pointer to access the fields+ _px <- peek $ p'px bunny+ _py <- peek $ p'py bunny+ c'drawTexture (texBunny state) (floor _px) (floor _py) (p'color bunny)+ )+ drawRectangle 0 0 screenWidth 40 black+ drawText ("bunnies: " ++ show (bunniesCount state)) 120 10 20 green+ drawText ("batched draw calls: " ++ show (1 + (bunniesCount state `div` 8192))) 320 10 20 maroon+ drawFPS 10 10+ endDrawing - forM_- [0 .. (bunniesCount state - 1)]- ( \(!i) ->- do- -- Same thing as before, but reading (`peek`) _and_ writing (`poke`)- let bunny = advancePtr (bunnies state) i- _px <- peek $ p'px bunny- _py <- peek $ p'py bunny- _sx <- peek $ p'sx bunny- _sy <- peek $ p'sy bunny- _color <- peek $ p'color bunny- let px' = _px + _sx- py' = _py + _sy- adjX = px' + halfTexWidth state- adjY = py' + halfTexHeight state- poke (p'px bunny) px'- poke (p'py bunny) py'- when (adjX > fromIntegral screenWidth || adjX < 0) $ poke (p'sx bunny) (-_sx)- when (adjY > fromIntegral screenHeight || adjY < 40) $ poke (p'sy bunny) (-_sy)- )+ forM_+ [0 .. (bunniesCount state - 1)]+ ( \(!i) ->+ do+ -- Same thing as before, but reading (`peek`) _and_ writing (`poke`)+ let bunny = advancePtr bptr i+ _px <- peek $ p'px bunny+ _py <- peek $ p'py bunny+ _sx <- peek $ p'sx bunny+ _sy <- peek $ p'sy bunny+ let px' = _px + _sx+ py' = _py + _sy+ adjX = px' + halfTexWidth state+ adjY = py' + halfTexHeight state+ poke (p'px bunny) px'+ poke (p'py bunny) py'+ when (adjX > fromIntegral screenWidth || adjX < 0) $ poke (p'sx bunny) (-_sx)+ when (adjY > fromIntegral screenHeight || adjY < 40) $ poke (p'sy bunny) (-_sy)+ ) - do- lDown <- isMouseButtonDown MouseButtonLeft- if lDown- then do- frameTime <- getFrameTime- let newBunnies = min (round (10000 * frameTime)) (maxBunnies - bunniesCount state)- mx <- realToFrac <$> c'getMouseX- my <- realToFrac <$> c'getMouseY- forM_- [bunniesCount state .. (bunniesCount state + newBunnies - 1)]- ( \(!i) ->- do- -- Creating elements uses `poke`, just like writing- let bunny = advancePtr (bunnies state) i- xSpeed <- (/ 60) . fromIntegral <$> c'getRandomValue (-250) 250- ySpeed <- (/ 60) . fromIntegral <$> c'getRandomValue (-250) 250- r <- fromIntegral <$> c'getRandomValue 50 240- g <- fromIntegral <$> c'getRandomValue 80 240- b <- fromIntegral <$> c'getRandomValue 100 240- ptr <- malloc- poke ptr (Color r g b 255)+ do+ lDown <- isMouseButtonDown MouseButtonLeft+ if lDown+ then do+ frameTime <- getFrameTime+ let newBunnies = min (round (10000 * frameTime)) (maxBunnies - bunniesCount state)+ mx <- realToFrac <$> c'getMouseX+ my <- realToFrac <$> c'getMouseY+ forM_+ [bunniesCount state .. (bunniesCount state + newBunnies - 1)]+ ( \(!i) ->+ do+ -- Creating elements uses `poke`, just like writing+ let bunny = advancePtr bptr i+ xSpeed <- (/ 60) . fromIntegral <$> c'getRandomValue (-250) 250+ ySpeed <- (/ 60) . fromIntegral <$> c'getRandomValue (-250) 250+ r <- fromIntegral <$> c'getRandomValue 50 240+ g <- fromIntegral <$> c'getRandomValue 80 240+ b <- fromIntegral <$> c'getRandomValue 100 240 - poke (p'px bunny) mx- poke (p'py bunny) my- poke (p'sx bunny) xSpeed- poke (p'sy bunny) ySpeed- poke (p'color bunny) ptr- )- return $ state {bunniesCount = bunniesCount state + newBunnies}- else return state+ poke (p'px bunny) mx+ poke (p'py bunny) my+ poke (p'sx bunny) xSpeed+ poke (p'sy bunny) ySpeed+ poke (p'color bunny) (Color r g b 255)+ )+ return $ state {bunniesCount = bunniesCount state + newBunnies}+ else return state shouldClose :: AppState -> IO Bool shouldClose _ = windowShouldClose@@ -223,7 +220,5 @@ -- Unload and free functions have to be manually called c'unloadTexture (texBunny state) free (texBunny state)- forM_ [0 .. (bunniesCount state - 1)] (\(!i) -> let bunny = advancePtr (bunnies state) i in free =<< peek (p'color bunny))- free (bunnies state) $(raylibApplication 'startup 'mainLoop 'shouldClose 'teardown)
+ flake.nix view
@@ -0,0 +1,91 @@+{+ inputs = {+ nixpkgs.url = "nixpkgs";+ };++ outputs = { self, nixpkgs, ... }@inputs:+ let+ supportedSystems = [ "x86_64-linux" "x86_64-darwin" ];+ forAllSystems' = nixpkgs.lib.genAttrs;+ forAllSystems = forAllSystems' supportedSystems;++ raylibRev = "04afba260f64ee2ea9ef0b4a6d2058c9ffdad66d";+ raylibHash = "sha256-WDXeTb6LbVw2ydX8w2Ql9Xq06+iB+VNoosiYWOGmj00=";+ rayguiRev = "85549da837fdb3844b77ede80922fca99276c8cd";+ rayguiHash = "sha256-KxiAWPc8jgt68ySVK2S3ocRTULqQlCZQVxxyD7BcOzI=";++ pkgsForSystem =+ system:+ import nixpkgs {+ inherit system;+ overlays = [+ (self: super: {+ raylib = super.raylib.overrideAttrs (old: {+ patches = [];+ version = "5.0.0";+ src = self.fetchFromGitHub {+ owner = "raysan5";+ repo = "raylib";+ rev = raylibRev;+ sha256 = raylibHash;+ };+ postFixup = "cp ../src/*.h $out/include/";+ });+ raygui = super.stdenv.mkDerivation { # A bit of a hack to get raygui working+ name = "raygui";+ version = "4.1.0";+ src = self.fetchFromGitHub {+ owner = "raysan5";+ repo = "raygui";+ rev = rayguiRev;+ sha256 = rayguiHash;+ };+ nativeBuildInputs = [];+ postFixup = "mkdir -p $out/include/ && cp ./src/raygui.h $out/include/ && cp ./examples/styles/*.h $out/include/";+ };+ # temporary fix for CI/CD+ # TODO: remove when github.com/NixOS/nixpkgs/pull/293296 gets merged+ glfw = super.glfw.overrideAttrs (old: {+ version = "3.4.0";+ src = self.fetchFromGitHub {+ owner = "glfw";+ repo = "GLFW";+ rev = "3.4";+ sha256 = "sha256-FcnQPDeNHgov1Z07gjFze0VMz2diOrpbKZCsI96ngz0=";+ };+ cmakeFlags = old.cmakeFlags ++ [ "-DGLFW_BUILD_WAYLAND=OFF" ];+ });+ })+ ];+ };+ depsForSystem =+ system:+ pkgs:+ with pkgs; (+ [raylib raygui]+ ++ lib.optionals stdenv.isLinux (with xorg; [libGL libX11 libXcursor libXext libXi libXinerama libXrandr])+ ++ lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [OpenGL Cocoa IOKit CoreVideo CoreAudio CoreFoundation])+ );+ in+ {+ devShells = forAllSystems (system:+ let+ pkgs = pkgsForSystem system;+ in+ {+ default =+ pkgs.mkShell rec {+ LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs;+ buildInputs = (with pkgs; [stdenv.cc ghc glfw cabal-install]) ++ depsForSystem system pkgs;+ };+ }+ );+ packages = forAllSystems (system: let+ pkgs = pkgsForSystem system;+ baseInputs = pkgs // pkgs.xorg // pkgs.haskellPackages // rec { systemDeps = depsForSystem system pkgs; buildExamples = false; };+ in {+ default = import ./default.nix baseInputs;+ examples = import ./default.nix (baseInputs // rec { buildExamples = true; });+ });+ };+}
h-raylib.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: h-raylib-version: 5.1.1.0+version: 5.1.2.0 synopsis: Raylib bindings for Haskell category: graphics description:@@ -34,6 +34,8 @@ raylib/**/*.c raylib/**/*.h raylib/**/*.m+ flake.nix+ default.nix source-repository head type: git@@ -284,7 +286,7 @@ Xi Xext - cc-options: -Wno-implicit-function-declaration -Wno-unused-result+ cc-options: -Wno-implicit-function-declaration -Wno-unused-result -D_GLFW_X11 elif (flag(platform-mac) || (flag(detect-platform) && os(osx))) frameworks: OpenGL Cocoa IOKit CoreVideo CoreAudio CoreFoundation
lib/rl_bindings.c view
@@ -126,17 +126,17 @@ UnloadShader(*a); } -RLBIND Ray *GetMouseRay_(Vector2 *a, Camera3D *b)+RLBIND Ray *GetScreenToWorldRay_(Vector2 *a, Camera3D *b) { Ray *ptr = (Ray *)malloc(sizeof(Ray));- *ptr = GetMouseRay(*a, *b);+ *ptr = GetScreenToWorldRay(*a, *b); return ptr; } -RLBIND Ray *GetViewRay_(Vector2 *a, Camera3D *b, float c, float d)+RLBIND Ray *GetScreenToWorldRayEx_(Vector2 *a, Camera3D *b, float c, float d) { Ray *ptr = (Ray *)malloc(sizeof(Ray));- *ptr = GetViewRay(*a, *b, c, d);+ *ptr = GetScreenToWorldRayEx(*a, *b, c, d); return ptr; } @@ -2578,6 +2578,11 @@ RLBIND int SetGamepadMappings_(const char *a) { return SetGamepadMappings(a);+}++RLBIND void SetGamepadVibration_(int a, float b, float c)+{+ SetGamepadVibration(a, b, c); } RLBIND bool IsMouseButtonPressed_(int a)
lib/rl_bindings.h view
@@ -54,9 +54,9 @@ void UnloadShader_(Shader *a); -Ray *GetMouseRay_(Vector2 *a, Camera3D *b);+Ray *GetScreenToWorldRay_(Vector2 *a, Camera3D *b); -Ray *GetViewRay_(Vector2 *a, Camera3D *b, float c, float d);+Ray *GetScreenToWorldRayEx_(Vector2 *a, Camera3D *b, float c, float d); Matrix *GetCameraMatrix_(Camera3D *a); @@ -943,6 +943,8 @@ float GetGamepadAxisMovement_(int a, int b); int SetGamepadMappings_(const char *a);++void SetGamepadVibration_(int a, float b, float c); bool IsMouseButtonPressed_(int a);
raygui/src/raygui.h view
@@ -26,7 +26,7 @@ * NOTES: * - WARNING: GuiLoadStyle() and GuiLoadStyle{Custom}() functions, allocate memory for * font atlas recs and glyphs, freeing that memory is (usually) up to the user,-* no unload function is explicitly provided... but note that GuiLoadStyleDefaulf() unloads+* no unload function is explicitly provided... but note that GuiLoadStyleDefault() unloads * by default any previously loaded font (texture, recs, glyphs). * - Global UI alpha (guiAlpha) is applied inside GuiDrawRectangle() and GuiDrawText() functions *@@ -317,9 +317,9 @@ #define RAYGUI_H #define RAYGUI_VERSION_MAJOR 4-#define RAYGUI_VERSION_MINOR 0+#define RAYGUI_VERSION_MINOR 1 #define RAYGUI_VERSION_PATCH 0-#define RAYGUI_VERSION "4.0"+#define RAYGUI_VERSION "4.1-dev" #if !defined(RAYGUI_STANDALONE) #include "raylib.h"@@ -563,7 +563,7 @@ TEXT_ALIGNMENT_VERTICAL, // Text vertical alignment inside text bounds (after border and padding) TEXT_WRAP_MODE // Text wrap-mode inside text bounds //TEXT_DECORATION // Text decoration: 0-None, 1-Underline, 2-Line-through, 3-Overline- //TEXT_DECORATION_THICK // Text decoration line thikness+ //TEXT_DECORATION_THICK // Text decoration line thickness } GuiDefaultProperty; // Other possible text properties:@@ -971,9 +971,9 @@ ICON_FOLDER = 217, ICON_FILE = 218, ICON_SAND_TIMER = 219,- ICON_220 = 220,- ICON_221 = 221,- ICON_222 = 222,+ ICON_WARNING = 220,+ ICON_HELP_BOX = 221,+ ICON_INFO_BOX = 222, ICON_223 = 223, ICON_224 = 224, ICON_225 = 225,@@ -1289,9 +1289,9 @@ 0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x40024002, 0x40024002, 0x7ffe4002, 0x00000000, // ICON_FOLDER 0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x00003ffc, // ICON_FILE 0x1ff00000, 0x20082008, 0x17d02fe8, 0x05400ba0, 0x09200540, 0x23881010, 0x2fe827c8, 0x00001ff0, // ICON_SAND_TIMER- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_220- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_221- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_222+ 0x01800000, 0x02400240, 0x05a00420, 0x09900990, 0x11881188, 0x21842004, 0x40024182, 0x00003ffc, // ICON_WARNING+ 0x7ffe0000, 0x4ff24002, 0x4c324ff2, 0x4f824c02, 0x41824f82, 0x41824002, 0x40024182, 0x00007ffe, // ICON_HELP_BOX+ 0x7ffe0000, 0x41824002, 0x40024182, 0x41824182, 0x41824182, 0x41824182, 0x40024182, 0x00007ffe, // ICON_INFO_BOX 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_223 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_224 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_225@@ -1327,7 +1327,7 @@ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_255 }; -// NOTE: We keep a pointer to the icons array, useful to point to other sets if required+// NOTE: A pointer to current icons array should be defined static unsigned int *guiIconsPtr = guiIcons; #endif // !RAYGUI_NO_ICONS && !RAYGUI_CUSTOM_ICONS@@ -1774,10 +1774,10 @@ { #define RAYGUI_MIN_SCROLLBAR_WIDTH 40 #define RAYGUI_MIN_SCROLLBAR_HEIGHT 40+ #define RAYGUI_MIN_MOUSE_WHEEL_SPEED 20 int result = 0; GuiState state = guiState;- float mouseWheelSpeed = 20.0f; // Default movement speed with mouse wheel Rectangle temp = { 0 }; if (view == NULL) view = &temp;@@ -1819,17 +1819,8 @@ }; // Make sure scroll bars have a minimum width/height- // NOTE: If content >>> bounds, size could be very small or even 0- if (horizontalScrollBar.width < RAYGUI_MIN_SCROLLBAR_WIDTH)- {- horizontalScrollBar.width = RAYGUI_MIN_SCROLLBAR_WIDTH;- mouseWheelSpeed = 30.0f; // TODO: Calculate speed increment based on content.height vs bounds.height- }- if (verticalScrollBar.height < RAYGUI_MIN_SCROLLBAR_HEIGHT)- {- verticalScrollBar.height = RAYGUI_MIN_SCROLLBAR_HEIGHT;- mouseWheelSpeed = 30.0f; // TODO: Calculate speed increment based on content.width vs bounds.width- }+ if (horizontalScrollBar.width < RAYGUI_MIN_SCROLLBAR_WIDTH) horizontalScrollBar.width = RAYGUI_MIN_SCROLLBAR_WIDTH;+ if (verticalScrollBar.height < RAYGUI_MIN_SCROLLBAR_HEIGHT) verticalScrollBar.height = RAYGUI_MIN_SCROLLBAR_HEIGHT; // Calculate view area (area without the scrollbars) *view = (GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)?@@ -1872,9 +1863,14 @@ #endif float wheelMove = GetMouseWheelMove(); + // Set scrolling speed with mouse wheel based on ratio between bounds and content+ Vector2 mouseWheelSpeed = { content.width / bounds.width, content.height / bounds.height };+ if (mouseWheelSpeed.x < RAYGUI_MIN_MOUSE_WHEEL_SPEED) mouseWheelSpeed.x = RAYGUI_MIN_MOUSE_WHEEL_SPEED;+ if (mouseWheelSpeed.y < RAYGUI_MIN_MOUSE_WHEEL_SPEED) mouseWheelSpeed.y = RAYGUI_MIN_MOUSE_WHEEL_SPEED;+ // Horizontal and vertical scrolling with mouse wheel- if (hasHorizontalScrollBar && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_LEFT_SHIFT))) scrollPos.x += wheelMove*mouseWheelSpeed;- else scrollPos.y += wheelMove*mouseWheelSpeed; // Vertical scroll+ if (hasHorizontalScrollBar && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_LEFT_SHIFT))) scrollPos.x += wheelMove*mouseWheelSpeed.x;+ else scrollPos.y += wheelMove*mouseWheelSpeed.y; // Vertical scroll } } @@ -2439,7 +2435,7 @@ // Text Box control // NOTE: Returns true on ENTER pressed (useful for data validation)-int GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)+int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) { #if !defined(RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN) #define RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN 40 // Frames to wait for autocursor movement@@ -2528,7 +2524,7 @@ // Add codepoint to text, at current cursor position // NOTE: Make sure we do not overflow buffer size- if (((multiline && (codepoint == (int)'\n')) || (codepoint >= 32)) && ((textLength + codepointSize) < bufferSize))+ if (((multiline && (codepoint == (int)'\n')) || (codepoint >= 32)) && ((textLength + codepointSize) < textSize)) { // Move forward data from cursor position for (int i = (textLength + codepointSize); i > textBoxCursorIndex; i--) text[i] = text[i - codepointSize];@@ -2726,7 +2722,7 @@ /* // Text Box control with multiple lines and word-wrap // NOTE: This text-box is readonly, no editing supported by default-bool GuiTextBoxMulti(Rectangle bounds, char *text, int bufferSize, bool editMode)+bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode) { bool pressed = false; @@ -2735,7 +2731,7 @@ GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_TOP); // TODO: Implement methods to calculate cursor position properly- pressed = GuiTextBox(bounds, text, bufferSize, editMode);+ pressed = GuiTextBox(bounds, text, textSize, editMode); GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_MIDDLE); GuiSetStyle(DEFAULT, TEXT_WRAP_MODE, TEXT_WRAP_NONE);@@ -3735,9 +3731,9 @@ int textWidth = GetTextWidth(message) + 2; Rectangle textBounds = { 0 };- textBounds.x = bounds.x + bounds.width/2 - textWidth/2;+ textBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING; textBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + RAYGUI_MESSAGEBOX_BUTTON_PADDING;- textBounds.width = (float)textWidth;+ textBounds.width = bounds.width - RAYGUI_MESSAGEBOX_BUTTON_PADDING*2; textBounds.height = bounds.height - RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 3*RAYGUI_MESSAGEBOX_BUTTON_PADDING - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT; // Draw control@@ -3941,6 +3937,7 @@ #define MAX_LINE_BUFFER_SIZE 256 bool tryBinary = false;+ if (!guiStyleLoaded) GuiLoadStyleDefault(); // Try reading the files as text file first FILE *rgsFile = fopen(fileName, "rt");@@ -5016,7 +5013,7 @@ buffer[i] = '\0'; // Set an end of string at this point counter++;- if (counter == RAYGUI_TEXTSPLIT_MAX_ITEMS) break;+ if (counter > RAYGUI_TEXTSPLIT_MAX_ITEMS) break; } } @@ -5178,6 +5175,7 @@ const int valueRange = maxValue - minValue; int sliderSize = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE);+ if (sliderSize < 1) sliderSize = 1; // TODO: Consider a minimum slider size // Calculate rectangles for all of the components arrowUpLeft = RAYGUI_CLITERAL(Rectangle){
raylib/examples/core/core_3d_picking.c view
@@ -60,7 +60,7 @@ { if (!collision.hit) {- ray = GetMouseRay(GetMousePosition(), camera);+ ray = GetScreenToWorldRay(GetMousePosition(), camera); // Check collision between ray and box collision = GetRayCollisionBox(ray,
+ raylib/examples/core/core_random_sequence.c view
@@ -0,0 +1,176 @@+/*******************************************************************************************+*+* raylib [core] example - Generates a random sequence+*+* Example originally created with raylib 5.0, last time updated with raylib 5.0+*+* Example contributed by Dalton Overmyer (@REDl3east) and reviewed by Ramon Santamaria (@raysan5)+*+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,+* BSD-like license that allows static linking with closed source software+*+* Copyright (c) 2023 Dalton Overmyer (@REDl3east)+*+********************************************************************************************/++#include "raylib.h"+#include "raymath.h"++#include <stdlib.h> // Required for: malloc() and free()++typedef struct ColorRect{+ Color c;+ Rectangle r;+} ColorRect;++static Color GenerateRandomColor();+static ColorRect* GenerateRandomColorRectSequence(float rectCount, float rectWidth, float screenWidth, float screenHeight);+static void ShuffleColorRectSequence(ColorRect* rectangles, int rectCount);+static void DrawTextCenterKeyHelp(const char* key, const char* text, int posX, int posY, int fontSize, Color color);++//------------------------------------------------------------------------------------+// Program main entry point+//------------------------------------------------------------------------------------+int main(void) {+ // Initialization+ //--------------------------------------------------------------------------------------+ const int screenWidth = 800;+ const int screenHeight = 450;++ InitWindow(screenWidth, screenHeight, "raylib [core] example - Generates a random sequence");++ int rectCount = 20;+ float rectSize = (float)screenWidth/rectCount;+ ColorRect* rectangles = GenerateRandomColorRectSequence(rectCount, rectSize, screenWidth, 0.75f * screenHeight);++ SetTargetFPS(60);+ //--------------------------------------------------------------------------------------++ // Main game loop+ while (!WindowShouldClose()) // Detect window close button or ESC key+ {+ // Update+ //----------------------------------------------------------------------------------++ if(IsKeyPressed(KEY_SPACE))+ {+ ShuffleColorRectSequence(rectangles, rectCount);+ }++ if(IsKeyPressed(KEY_UP))+ {+ rectCount++;+ rectSize = (float)screenWidth/rectCount;+ free(rectangles);+ rectangles = GenerateRandomColorRectSequence(rectCount, rectSize, screenWidth, 0.75f * screenHeight);+ }++ if(IsKeyPressed(KEY_DOWN))+ {+ if(rectCount >= 4){+ rectCount--;+ rectSize = (float)screenWidth/rectCount;+ free(rectangles);+ rectangles = GenerateRandomColorRectSequence(rectCount, rectSize, screenWidth, 0.75f * screenHeight);+ }+ }++ // Draw+ //----------------------------------------------------------------------------------+ BeginDrawing();++ ClearBackground(RAYWHITE);+ + int fontSize = 20;+ for(int x=0;x<rectCount;x++)+ {+ DrawRectangleRec(rectangles[x].r, rectangles[x].c);+ DrawTextCenterKeyHelp("SPACE", "to shuffle the sequence.", 10, screenHeight - 96, fontSize, BLACK);+ DrawTextCenterKeyHelp("UP", "to add a rectangle and generate a new sequence.", 10, screenHeight - 64, fontSize, BLACK);+ DrawTextCenterKeyHelp("DOWN", "to remove a rectangle and generate a new sequence.", 10, screenHeight - 32, fontSize, BLACK);+ }++ const char* rectCountText = TextFormat("%d rectangles", rectCount);+ int rectCountTextSize = MeasureText(rectCountText, fontSize);+ DrawText(rectCountText, screenWidth - rectCountTextSize - 10, 10, fontSize, BLACK);++ DrawFPS(10, 10);++ EndDrawing();+ //----------------------------------------------------------------------------------+ }++ // De-Initialization+ //--------------------------------------------------------------------------------------++ free(rectangles);+ CloseWindow(); // Close window and OpenGL context+ //--------------------------------------------------------------------------------------++ return 0;+}++static Color GenerateRandomColor()+{+ return CLITERAL(Color){+ GetRandomValue(0, 255),+ GetRandomValue(0, 255),+ GetRandomValue(0, 255),+ 255,+ };+}++static ColorRect* GenerateRandomColorRectSequence(float rectCount, float rectWidth, float screenWidth, float screenHeight){+ int *seq = LoadRandomSequence(rectCount, 0, rectCount-1);+ ColorRect* rectangles = (ColorRect *)malloc(rectCount*sizeof(ColorRect));++ float rectSeqWidth = rectCount * rectWidth;+ int startX = (screenWidth - rectSeqWidth) * 0.5f;++ for(int x=0;x<rectCount;x++){+ int rectHeight = Remap(seq[x], 0, rectCount-1, 0, screenHeight);+ rectangles[x].c = GenerateRandomColor();+ rectangles[x].r = CLITERAL(Rectangle){+ startX + x * rectWidth, screenHeight - rectHeight, rectWidth, rectHeight+ };+ }+ UnloadRandomSequence(seq);+ return rectangles;+}++static void ShuffleColorRectSequence(ColorRect* rectangles, int rectCount)+{+ int *seq = LoadRandomSequence(rectCount, 0, rectCount-1);+ for(int i1=0;i1<rectCount;i1++){+ ColorRect* r1 = &rectangles[i1];+ ColorRect* r2 = &rectangles[seq[i1]];++ // swap only the color and height+ ColorRect tmp = *r1;+ r1->c = r2->c;+ r1->r.height = r2->r.height;+ r1->r.y = r2->r.y;+ r2->c = tmp.c;+ r2->r.height = tmp.r.height;+ r2->r.y = tmp.r.y;++ }+ UnloadRandomSequence(seq);+}++static void DrawTextCenterKeyHelp(const char* key, const char* text, int posX, int posY, int fontSize, Color color)+{+ int spaceSize = MeasureText(" ", fontSize); + int pressSize = MeasureText("Press", fontSize); + int keySize = MeasureText(key, fontSize); + int textSize = MeasureText(text, fontSize); + int totalSize = pressSize + 2 * spaceSize + keySize + 2 * spaceSize + textSize;+ int textSizeCurrent = 0;++ DrawText("Press", posX, posY, fontSize, color);+ textSizeCurrent += pressSize + 2 * spaceSize;+ DrawText(key, posX + textSizeCurrent, posY, fontSize, RED);+ DrawRectangle(posX + textSizeCurrent, posY + fontSize, keySize, 3, RED);+ textSizeCurrent += keySize + 2 * spaceSize;+ DrawText(text, posX + textSizeCurrent, posY, fontSize, color);+}
+ raylib/examples/models/models_bone_socket.c view
@@ -0,0 +1,177 @@+/*******************************************************************************************+*+* raylib [core] example - Using bones as socket for calculating the positioning of something+* +* Example originally created with raylib 4.5, last time updated with raylib 4.5+*+* Example contributed by iP (@ipzaur) and reviewed by Ramon Santamaria (@raysan5)+*+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,+* BSD-like license that allows static linking with closed source software+*+* Copyright (c) 2024 iP (@ipzaur)+*+********************************************************************************************/++#include "raylib.h"++#include "raymath.h"++#define BONE_SOCKETS 3+#define BONE_SOCKET_HAT 0+#define BONE_SOCKET_HAND_R 1+#define BONE_SOCKET_HAND_L 2++//------------------------------------------------------------------------------------+// Program main entry point+//------------------------------------------------------------------------------------+int main(void)+{+ // Initialization+ //--------------------------------------------------------------------------------------+ const int screenWidth = 800;+ const int screenHeight = 450;++ InitWindow(screenWidth, screenHeight, "raylib [models] example - bone socket");++ // Define the camera to look into our 3d world+ Camera camera = { 0 };+ camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position+ camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)+ camera.fovy = 45.0f; // Camera field-of-view Y+ camera.projection = CAMERA_PERSPECTIVE; // Camera projection type++ // Load gltf model+ Model characterModel = LoadModel("resources/models/gltf/greenman.glb"); // Load character model+ Model equipModel[BONE_SOCKETS] = {+ LoadModel("resources/models/gltf/greenman_hat.glb"), // Index for the hat model is the same as BONE_SOCKET_HAT+ LoadModel("resources/models/gltf/greenman_sword.glb"), // Index for the sword model is the same as BONE_SOCKET_HAND_R+ LoadModel("resources/models/gltf/greenman_shield.glb") // Index for the shield model is the same as BONE_SOCKET_HAND_L+ };+ + bool showEquip[3] = { true, true, true }; // Toggle on/off equip++ // Load gltf model animations+ int animsCount = 0;+ unsigned int animIndex = 0;+ unsigned int animCurrentFrame = 0;+ ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/greenman.glb", &animsCount);++ // indices of bones for sockets+ int boneSocketIndex[BONE_SOCKETS] = { -1, -1, -1 };++ // search bones for sockets + for (int i = 0; i < characterModel.boneCount; i++)+ {+ if (TextIsEqual(characterModel.bones[i].name, "socket_hat"))+ {+ boneSocketIndex[BONE_SOCKET_HAT] = i;+ continue;+ }+ + if (TextIsEqual(characterModel.bones[i].name, "socket_hand_R"))+ {+ boneSocketIndex[BONE_SOCKET_HAND_R] = i;+ continue;+ }+ + if (TextIsEqual(characterModel.bones[i].name, "socket_hand_L"))+ {+ boneSocketIndex[BONE_SOCKET_HAND_L] = i;+ continue;+ }+ }++ Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position+ unsigned short angle = 0; // Set angle for rotate character++ DisableCursor(); // Limit cursor to relative movement inside the window++ SetTargetFPS(60); // Set our game to run at 60 frames-per-second+ //--------------------------------------------------------------------------------------++ // Main game loop+ while (!WindowShouldClose()) // Detect window close button or ESC key+ {+ // Update+ //----------------------------------------------------------------------------------+ UpdateCamera(&camera, CAMERA_THIRD_PERSON);+ + // Rotate character+ if (IsKeyDown(KEY_F)) angle = (angle + 1)%360;+ else if (IsKeyDown(KEY_H)) angle = (360 + angle - 1)%360;++ // Select current animation+ if (IsKeyPressed(KEY_T)) animIndex = (animIndex + 1)%animsCount;+ else if (IsKeyPressed(KEY_G)) animIndex = (animIndex + animsCount - 1)%animsCount;++ // Toggle shown of equip+ if (IsKeyPressed(KEY_ONE)) showEquip[BONE_SOCKET_HAT] = !showEquip[BONE_SOCKET_HAT];+ if (IsKeyPressed(KEY_TWO)) showEquip[BONE_SOCKET_HAND_R] = !showEquip[BONE_SOCKET_HAND_R];+ if (IsKeyPressed(KEY_THREE)) showEquip[BONE_SOCKET_HAND_L] = !showEquip[BONE_SOCKET_HAND_L];+ + // Update model animation+ ModelAnimation anim = modelAnimations[animIndex];+ animCurrentFrame = (animCurrentFrame + 1)%anim.frameCount;+ UpdateModelAnimation(characterModel, anim, animCurrentFrame);+ //----------------------------------------------------------------------------------++ // Draw+ //----------------------------------------------------------------------------------+ BeginDrawing();++ ClearBackground(RAYWHITE);++ BeginMode3D(camera);+ // Draw character+ Quaternion characterRotate = QuaternionFromAxisAngle((Vector3){ 0.0f, 1.0f, 0.0f }, angle*DEG2RAD);+ characterModel.transform = MatrixMultiply(QuaternionToMatrix(characterRotate), MatrixTranslate(position.x, position.y, position.z));+ UpdateModelAnimation(characterModel, anim, animCurrentFrame);+ DrawMesh(characterModel.meshes[0], characterModel.materials[1], characterModel.transform);++ // Draw equipments (hat, sword, shield)+ for (int i = 0; i < BONE_SOCKETS; i++)+ {+ if (!showEquip[i]) continue;++ Transform *transform = &anim.framePoses[animCurrentFrame][boneSocketIndex[i]];+ Quaternion inRotation = characterModel.bindPose[boneSocketIndex[i]].rotation;+ Quaternion outRotation = transform->rotation;+ + // Calculate socket rotation (angle between bone in initial pose and same bone in current animation frame)+ Quaternion rotate = QuaternionMultiply(outRotation, QuaternionInvert(inRotation));+ Matrix matrixTransform = QuaternionToMatrix(rotate);+ // Translate socket to its position in the current animation+ matrixTransform = MatrixMultiply(matrixTransform, MatrixTranslate(transform->translation.x, transform->translation.y, transform->translation.z));+ // Transform the socket using the transform of the character (angle and translate)+ matrixTransform = MatrixMultiply(matrixTransform, characterModel.transform);+ + // Draw mesh at socket position with socket angle rotation+ DrawMesh(equipModel[i].meshes[0], equipModel[i].materials[1], matrixTransform);+ }++ DrawGrid(10, 1.0f);+ EndMode3D();++ DrawText("Use the T/G to switch animation", 10, 10, 20, GRAY);+ DrawText("Use the F/H to rotate character left/right", 10, 35, 20, GRAY);+ DrawText("Use the 1,2,3 to toggle shown of hat, sword and shield", 10, 60, 20, GRAY);++ EndDrawing();+ //----------------------------------------------------------------------------------+ }++ // De-Initialization+ //--------------------------------------------------------------------------------------+ UnloadModelAnimations(modelAnimations, animsCount);+ UnloadModel(characterModel); // Unload character model and meshes/material+ + // Unload equipment model and meshes/material+ for (int i = 0; i < BONE_SOCKETS; i++) UnloadModel(equipModel[i]);++ CloseWindow(); // Close window and OpenGL context+ //--------------------------------------------------------------------------------------++ return 0;+}
raylib/examples/models/models_first_person_maze.c view
@@ -34,7 +34,6 @@ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) camera.fovy = 45.0f; // Camera field-of-view Y camera.projection = CAMERA_PERSPECTIVE; // Camera projection type- Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position Image imMap = LoadImage("resources/cubicmap.png"); // Load cubicmap image (RAM) Texture2D cubicmap = LoadTextureFromImage(imMap); // Convert image to texture to display (VRAM)
raylib/examples/models/models_loading.c view
@@ -109,7 +109,7 @@ if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { // Check collision between ray and box- if (GetRayCollisionBox(GetMouseRay(GetMousePosition(), camera), bounds).hit) selected = !selected;+ if (GetRayCollisionBox(GetScreenToWorldRay(GetMousePosition(), camera), bounds).hit) selected = !selected; else selected = false; } //----------------------------------------------------------------------------------
raylib/examples/models/models_loading_vox.c view
@@ -17,117 +17,189 @@ #include "raymath.h" // Required for: MatrixTranslate() -#define MAX_VOX_FILES 3+#define MAX_VOX_FILES 4 +#define RLIGHTS_IMPLEMENTATION+#include "rlights.h"++#if defined(PLATFORM_DESKTOP)+#define GLSL_VERSION 330+#else // PLATFORM_ANDROID, PLATFORM_WEB+#define GLSL_VERSION 100+#endif+ //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ int main(void) {- // Initialization- //--------------------------------------------------------------------------------------- const int screenWidth = 800;- const int screenHeight = 450;+ // Initialization+ //--------------------------------------------------------------------------------------+ const int screenWidth = 800;+ const int screenHeight = 450; - const char *voxFileNames[] = {- "resources/models/vox/chr_knight.vox",- "resources/models/vox/chr_sword.vox",- "resources/models/vox/monu9.vox"- };+ const char* voxFileNames[] = {+ "resources/models/vox/chr_knight.vox",+ "resources/models/vox/chr_sword.vox",+ "resources/models/vox/monu9.vox",+ "resources/models/vox/fez.vox"+ }; - InitWindow(screenWidth, screenHeight, "raylib [models] example - magicavoxel loading");+ InitWindow(screenWidth, screenHeight, "raylib [models] example - magicavoxel loading"); - // Define the camera to look into our 3d world- Camera camera = { 0 };- camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position- camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point- camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)- camera.fovy = 45.0f; // Camera field-of-view Y- camera.projection = CAMERA_PERSPECTIVE; // Camera projection type+ // Define the camera to look into our 3d world+ Camera camera = { 0 };+ camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position+ camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)+ camera.fovy = 45.0f; // Camera field-of-view Y+ camera.projection = CAMERA_PERSPECTIVE; // Camera projection type - // Load MagicaVoxel files- Model models[MAX_VOX_FILES] = { 0 };+ //--------------------------------------------------------------------------------------+ // Load MagicaVoxel files+ Model models[MAX_VOX_FILES] = { 0 }; - for (int i = 0; i < MAX_VOX_FILES; i++)- {- // Load VOX file and measure time- double t0 = GetTime()*1000.0;- models[i] = LoadModel(voxFileNames[i]);- double t1 = GetTime()*1000.0;+ for (int i = 0; i < MAX_VOX_FILES; i++)+ {+ // Load VOX file and measure time+ double t0 = GetTime() * 1000.0;+ models[i] = LoadModel(voxFileNames[i]);+ double t1 = GetTime() * 1000.0; - TraceLog(LOG_WARNING, TextFormat("[%s] File loaded in %.3f ms", voxFileNames[i], t1 - t0));+ TraceLog(LOG_WARNING, TextFormat("[%s] File loaded in %.3f ms", voxFileNames[i], t1 - t0)); - // Compute model translation matrix to center model on draw position (0, 0 , 0)- BoundingBox bb = GetModelBoundingBox(models[i]);- Vector3 center = { 0 };- center.x = bb.min.x + (((bb.max.x - bb.min.x)/2));- center.z = bb.min.z + (((bb.max.z - bb.min.z)/2));+ // Compute model translation matrix to center model on draw position (0, 0 , 0)+ BoundingBox bb = GetModelBoundingBox(models[i]);+ Vector3 center = { 0 };+ center.x = bb.min.x + (((bb.max.x - bb.min.x) / 2));+ center.z = bb.min.z + (((bb.max.z - bb.min.z) / 2)); - Matrix matTranslate = MatrixTranslate(-center.x, 0, -center.z);- models[i].transform = matTranslate;- }+ Matrix matTranslate = MatrixTranslate(-center.x, 0, -center.z);+ models[i].transform = matTranslate;+ } - int currentModel = 0;+ int currentModel = 0; - SetTargetFPS(60); // Set our game to run at 60 frames-per-second- //--------------------------------------------------------------------------------------+ //--------------------------------------------------------------------------------------+ // Load voxel shader+ Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/voxel_lighting.vs", GLSL_VERSION),+ TextFormat("resources/shaders/glsl%i/voxel_lighting.fs", GLSL_VERSION)); - // Main game loop- while (!WindowShouldClose()) // Detect window close button or ESC key- {- // Update- //----------------------------------------------------------------------------------- UpdateCamera(&camera, CAMERA_ORBITAL);+ // Get some required shader locations+ shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");+ // NOTE: "matModel" location name is automatically assigned on shader loading, + // no need to get the location again if using that uniform name+ //shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(shader, "matModel"); - // Cycle between models on mouse click- if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1)%MAX_VOX_FILES;+ // Ambient light level (some basic lighting)+ int ambientLoc = GetShaderLocation(shader, "ambient");+ SetShaderValue(shader, ambientLoc, (float[4]) { 0.1f, 0.1f, 0.1f, 1.0f }, SHADER_UNIFORM_VEC4); - // Cycle between models on key pressed- if (IsKeyPressed(KEY_RIGHT))- {- currentModel++;- if (currentModel >= MAX_VOX_FILES) currentModel = 0;- }- else if (IsKeyPressed(KEY_LEFT))- {- currentModel--;- if (currentModel < 0) currentModel = MAX_VOX_FILES - 1;- }- //----------------------------------------------------------------------------------+ // Assign out lighting shader to model+ for (int i = 0; i < MAX_VOX_FILES; i++)+ {+ Model m = models[i];+ for (int j = 0; j < m.materialCount; j++)+ {+ m.materials[j].shader = shader;+ }+ } - // Draw- //----------------------------------------------------------------------------------- BeginDrawing();+ // Create lights+ Light lights[MAX_LIGHTS] = { 0 };+ lights[0] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, -20 }, Vector3Zero(), GRAY, shader);+ lights[1] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, 20 }, Vector3Zero(), GRAY, shader);+ lights[2] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, 20 }, Vector3Zero(), GRAY, shader);+ lights[3] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, -20 }, Vector3Zero(), GRAY, shader); - ClearBackground(RAYWHITE); - // Draw 3D model- BeginMode3D(camera);+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second - DrawModel(models[currentModel], (Vector3){ 0, 0, 0 }, 1.0f, WHITE);- DrawGrid(10, 1.0);+ //--------------------------------------------------------------------------------------+ Vector3 modelpos = { 0 };+ Vector3 camerarot = { 0 }; - EndMode3D();+ // Main game loop+ while (!WindowShouldClose()) // Detect window close button or ESC key+ {+ // Update+ //----------------------------------------------------------------------------------+ if (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE))+ {+ const Vector2 mouseDelta = GetMouseDelta();+ camerarot.x = mouseDelta.x * 0.05f;+ camerarot.y = mouseDelta.y * 0.05f;+ }+ else+ {+ camerarot.x = 0;+ camerarot.y = 0;+ } - // Display info- DrawRectangle(10, 400, 310, 30, Fade(SKYBLUE, 0.5f));- DrawRectangleLines(10, 400, 310, 30, Fade(DARKBLUE, 0.5f));- DrawText("MOUSE LEFT BUTTON to CYCLE VOX MODELS", 40, 410, 10, BLUE);- DrawText(TextFormat("File: %s", GetFileName(voxFileNames[currentModel])), 10, 10, 20, GRAY);+ UpdateCameraPro(&camera,+ (Vector3) {+ (IsKeyDown(KEY_W) || IsKeyDown(KEY_UP)) * 0.1f - // Move forward-backward+ (IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN)) * 0.1f,+ (IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT)) * 0.1f - // Move right-left+ (IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT)) * 0.1f,+ 0.0f // Move up-down+ },+ camerarot,+ GetMouseWheelMove() * -2.0f); // Move to target (zoom) - EndDrawing();- //----------------------------------------------------------------------------------- }+ // Cycle between models on mouse click+ if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1) % MAX_VOX_FILES; - // De-Initialization- //--------------------------------------------------------------------------------------- // Unload models data (GPU VRAM)- for (int i = 0; i < MAX_VOX_FILES; i++) UnloadModel(models[i]);+ // Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f })+ float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z };+ SetShaderValue(shader, shader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3); - CloseWindow(); // Close window and OpenGL context- //--------------------------------------------------------------------------------------+ // Update light values (actually, only enable/disable them)+ for (int i = 0; i < MAX_LIGHTS; i++) UpdateLightValues(shader, lights[i]); - return 0;+ //----------------------------------------------------------------------------------+ // Draw+ //----------------------------------------------------------------------------------+ BeginDrawing();++ ClearBackground(RAYWHITE);++ // Draw 3D model+ BeginMode3D(camera);++ DrawModel(models[currentModel], modelpos, 1.0f, WHITE);+ DrawGrid(10, 1.0);++ // Draw spheres to show where the lights are+ for (int i = 0; i < MAX_LIGHTS; i++)+ {+ if (lights[i].enabled) DrawSphereEx(lights[i].position, 0.2f, 8, 8, lights[i].color);+ else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(lights[i].color, 0.3f));+ }++ EndMode3D();++ // Display info+ DrawRectangle(10, 400, 340, 60, Fade(SKYBLUE, 0.5f));+ DrawRectangleLines(10, 400, 340, 60, Fade(DARKBLUE, 0.5f));+ DrawText("MOUSE LEFT BUTTON to CYCLE VOX MODELS", 40, 410, 10, BLUE);+ DrawText("MOUSE MIDDLE BUTTON to ZOOM OR ROTATE CAMERA", 40, 420, 10, BLUE);+ DrawText("UP-DOWN-LEFT-RIGHT KEYS to MOVE CAMERA", 40, 430, 10, BLUE);+ DrawText(TextFormat("File: %s", GetFileName(voxFileNames[currentModel])), 10, 10, 20, GRAY);++ EndDrawing();+ //----------------------------------------------------------------------------------+ }++ // De-Initialization+ //--------------------------------------------------------------------------------------+ // Unload models data (GPU VRAM)+ for (int i = 0; i < MAX_VOX_FILES; i++) UnloadModel(models[i]);++ CloseWindow(); // Close window and OpenGL context+ //--------------------------------------------------------------------------------------++ return 0; }
raylib/examples/models/models_mesh_picking.c view
@@ -88,7 +88,7 @@ Color cursorColor = WHITE; // Get ray and test against objects- ray = GetMouseRay(GetMousePosition(), camera);+ ray = GetScreenToWorldRay(GetMousePosition(), camera); // Check ray collision against ground quad RayCollision groundHitInfo = GetRayCollisionQuad(ray, g0, g1, g2, g3);
+ raylib/examples/models/rlights.h view
@@ -0,0 +1,170 @@+/**********************************************************************************************+*+* raylib.lights - Some useful functions to deal with lights data+*+* CONFIGURATION:+*+* #define RLIGHTS_IMPLEMENTATION+* Generates the implementation of the library into the included file.+* If not defined, the library is in header only mode and can be included in other headers +* or source files without problems. But only ONE file should hold the implementation.+*+* LICENSE: zlib/libpng+*+* Copyright (c) 2017-2024 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)+*+* This software is provided "as-is", without any express or implied warranty. In no event+* will the authors be held liable for any damages arising from the use of this software.+*+* Permission is granted to anyone to use this software for any purpose, including commercial+* applications, and to alter it and redistribute it freely, subject to the following restrictions:+*+* 1. The origin of this software must not be misrepresented; you must not claim that you+* wrote the original software. If you use this software in a product, an acknowledgment+* in the product documentation would be appreciated but is not required.+*+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented+* as being the original software.+*+* 3. This notice may not be removed or altered from any source distribution.+*+**********************************************************************************************/++#ifndef RLIGHTS_H+#define RLIGHTS_H++//----------------------------------------------------------------------------------+// Defines and Macros+//----------------------------------------------------------------------------------+#define MAX_LIGHTS 4 // Max dynamic lights supported by shader++//----------------------------------------------------------------------------------+// Types and Structures Definition+//----------------------------------------------------------------------------------++// Light data+typedef struct { + int type;+ bool enabled;+ Vector3 position;+ Vector3 target;+ Color color;+ float attenuation;+ + // Shader locations+ int enabledLoc;+ int typeLoc;+ int positionLoc;+ int targetLoc;+ int colorLoc;+ int attenuationLoc;+} Light;++// Light type+typedef enum {+ LIGHT_DIRECTIONAL = 0,+ LIGHT_POINT+} LightType;++#ifdef __cplusplus+extern "C" { // Prevents name mangling of functions+#endif++//----------------------------------------------------------------------------------+// Module Functions Declaration+//----------------------------------------------------------------------------------+Light CreateLight(int type, Vector3 position, Vector3 target, Color color, Shader shader); // Create a light and get shader locations+void UpdateLightValues(Shader shader, Light light); // Send light properties to shader++#ifdef __cplusplus+}+#endif++#endif // RLIGHTS_H+++/***********************************************************************************+*+* RLIGHTS IMPLEMENTATION+*+************************************************************************************/++#if defined(RLIGHTS_IMPLEMENTATION)++#include "raylib.h"++//----------------------------------------------------------------------------------+// Defines and Macros+//----------------------------------------------------------------------------------+// ...++//----------------------------------------------------------------------------------+// Types and Structures Definition+//----------------------------------------------------------------------------------+// ...++//----------------------------------------------------------------------------------+// Global Variables Definition+//----------------------------------------------------------------------------------+static int lightsCount = 0; // Current amount of created lights++//----------------------------------------------------------------------------------+// Module specific Functions Declaration+//----------------------------------------------------------------------------------+// ...++//----------------------------------------------------------------------------------+// Module Functions Definition+//----------------------------------------------------------------------------------++// Create a light and get shader locations+Light CreateLight(int type, Vector3 position, Vector3 target, Color color, Shader shader)+{+ Light light = { 0 };++ if (lightsCount < MAX_LIGHTS)+ {+ light.enabled = true;+ light.type = type;+ light.position = position;+ light.target = target;+ light.color = color;++ // NOTE: Lighting shader naming must be the provided ones+ light.enabledLoc = GetShaderLocation(shader, TextFormat("lights[%i].enabled", lightsCount));+ light.typeLoc = GetShaderLocation(shader, TextFormat("lights[%i].type", lightsCount));+ light.positionLoc = GetShaderLocation(shader, TextFormat("lights[%i].position", lightsCount));+ light.targetLoc = GetShaderLocation(shader, TextFormat("lights[%i].target", lightsCount));+ light.colorLoc = GetShaderLocation(shader, TextFormat("lights[%i].color", lightsCount));++ UpdateLightValues(shader, light);+ + lightsCount++;+ }++ return light;+}++// Send light properties to shader+// NOTE: Light shader locations should be available +void UpdateLightValues(Shader shader, Light light)+{+ // Send to shader light enabled state and type+ SetShaderValue(shader, light.enabledLoc, &light.enabled, SHADER_UNIFORM_INT);+ SetShaderValue(shader, light.typeLoc, &light.type, SHADER_UNIFORM_INT);++ // Send to shader light position values+ float position[3] = { light.position.x, light.position.y, light.position.z };+ SetShaderValue(shader, light.positionLoc, position, SHADER_UNIFORM_VEC3);++ // Send to shader light target position values+ float target[3] = { light.target.x, light.target.y, light.target.z };+ SetShaderValue(shader, light.targetLoc, target, SHADER_UNIFORM_VEC3);++ // Send to shader light color values+ float color[4] = { (float)light.color.r/(float)255, (float)light.color.g/(float)255, + (float)light.color.b/(float)255, (float)light.color.a/(float)255 };+ SetShaderValue(shader, light.colorLoc, color, SHADER_UNIFORM_VEC4);+}++#endif // RLIGHTS_IMPLEMENTATION
raylib/examples/others/raylib_opengl_interop.c view
@@ -26,7 +26,7 @@ #include "raylib.h" -#if defined(PLATFORM_DESKTOP)+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL) #if defined(GRAPHICS_API_OPENGL_ES2) #include "glad_gles2.h" // Required for: OpenGL functionality #define glGenVertexArrays glGenVertexArraysOES@@ -35,6 +35,7 @@ #define GLSL_VERSION 100 #else #if defined(__APPLE__)+ #define GL_SILENCE_DEPRECATION // Silence Opengl API deprecation warnings #include <OpenGL/gl3.h> // OpenGL 3 library for OSX #include <OpenGL/gl3ext.h> // OpenGL 3 extensions library for OSX #else
raylib/examples/text/text_codepoints_loading.c view
@@ -60,7 +60,6 @@ bool showFontAtlas = false; int codepointSize = 0;- int codepoint = 0; char *ptr = text; SetTargetFPS(60); // Set our game to run at 60 frames-per-second@@ -77,13 +76,13 @@ if (IsKeyPressed(KEY_RIGHT)) { // Get next codepoint in string and move pointer- codepoint = GetCodepointNext(ptr, &codepointSize);+ GetCodepointNext(ptr, &codepointSize); ptr += codepointSize; } else if (IsKeyPressed(KEY_LEFT)) { // Get previous codepoint in string and move pointer- codepoint = GetCodepointPrevious(ptr, &codepointSize);+ GetCodepointPrevious(ptr, &codepointSize); ptr -= codepointSize; } //----------------------------------------------------------------------------------
raylib/examples/text/text_draw_3d.c view
@@ -195,7 +195,7 @@ // Handle clicking the cube if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {- Ray ray = GetMouseRay(GetMousePosition(), camera);+ Ray ray = GetScreenToWorldRay(GetMousePosition(), camera); // Check collision between ray and box RayCollision collision = GetRayCollisionBox(ray,
raylib/examples/textures/textures_image_generation.c view
@@ -13,7 +13,7 @@ #include "raylib.h" -#define NUM_TEXTURES 9 // Currently we have 8 generation algorithms but some are have multiple purposes (Linear and Square Gradients)+#define NUM_TEXTURES 9 // Currently we have 8 generation algorithms but some have multiple purposes (Linear and Square Gradients) //------------------------------------------------------------------------------------ // Program main entry point
raylib/src/config.h view
@@ -81,6 +81,7 @@ #define MAX_GAMEPADS 4 // Maximum number of gamepads supported #define MAX_GAMEPAD_AXIS 8 // Maximum number of axis supported (per gamepad) #define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad)+#define MAX_GAMEPAD_VIBRATION_TIME 2.0f // Maximum vibration time in seconds #define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported #define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue #define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue
raylib/src/external/cgltf.h view
@@ -63,9 +63,14 @@ * By passing null for the output pointer, users can find out how many floats are required in the * output buffer. *+ * `cgltf_accessor_unpack_indices` reads in the index data from an accessor. Assumes that+ * `cgltf_load_buffers` has already been called. By passing null for the output pointer, users can+ * find out how many indices are required in the output buffer. Returns 0 if the accessor is+ * sparse or if the output component size is less than the accessor's component size.+ * * `cgltf_num_components` is a tiny utility that tells you the dimensionality of * a certain accessor type. This can be used before `cgltf_accessor_unpack_floats` to help allocate- * the necessary amount of memory. `cgltf_component_size` and `cgltf_calc_size` exist for + * the necessary amount of memory. `cgltf_component_size` and `cgltf_calc_size` exist for * similar purposes. * * `cgltf_accessor_read_float` reads a certain element from a non-sparse accessor and converts it to@@ -75,7 +80,7 @@ * * `cgltf_accessor_read_uint` is similar to its floating-point counterpart, but limited to reading * vector types and does not support matrix types. The passed-in element size is the number of uints- * in the output buffer, which should be in the range [1, 4]. Returns false if the passed-in + * in the output buffer, which should be in the range [1, 4]. Returns false if the passed-in * element_size is too small, or if the accessor is sparse. * * `cgltf_accessor_read_index` is similar to its floating-point counterpart, but it returns size_t@@ -197,6 +202,7 @@ typedef enum cgltf_primitive_type {+ cgltf_primitive_type_invalid, cgltf_primitive_type_points, cgltf_primitive_type_lines, cgltf_primitive_type_line_loop,@@ -499,6 +505,11 @@ cgltf_texture_view anisotropy_texture; } cgltf_anisotropy; +typedef struct cgltf_dispersion+{+ cgltf_float dispersion;+} cgltf_dispersion;+ typedef struct cgltf_material { char* name;@@ -513,6 +524,7 @@ cgltf_bool has_emissive_strength; cgltf_bool has_iridescence; cgltf_bool has_anisotropy;+ cgltf_bool has_dispersion; cgltf_pbr_metallic_roughness pbr_metallic_roughness; cgltf_pbr_specular_glossiness pbr_specular_glossiness; cgltf_clearcoat clearcoat;@@ -524,6 +536,7 @@ cgltf_emissive_strength emissive_strength; cgltf_iridescence iridescence; cgltf_anisotropy anisotropy;+ cgltf_dispersion dispersion; cgltf_texture_view normal_texture; cgltf_texture_view occlusion_texture; cgltf_texture_view emissive_texture;@@ -838,7 +851,7 @@ cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type); cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor* accessor, cgltf_float* out, cgltf_size float_count);-cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_uint* out, cgltf_size index_count);+cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* out, cgltf_size out_component_size, cgltf_size index_count); /* this function is deprecated and will be removed in the future; use cgltf_extras::data instead */ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* extras, char* dest, cgltf_size* dest_size);@@ -938,8 +951,8 @@ #ifndef CGLTF_CONSTS-static const cgltf_size GlbHeaderSize = 12;-static const cgltf_size GlbChunkHeaderSize = 8;+#define GlbHeaderSize 12+#define GlbChunkHeaderSize 8 static const uint32_t GlbVersion = 2; static const uint32_t GlbMagic = 0x46546C67; static const uint32_t GlbMagicJsonChunk = 0x4E4F534A;@@ -1033,7 +1046,7 @@ fclose(file); return cgltf_result_out_of_memory; }- + cgltf_size read_size = fread(file_data, 1, file_size, file); fclose(file);@@ -1141,7 +1154,7 @@ // JSON chunk: length uint32_t json_length; memcpy(&json_length, json_chunk, 4);- if (GlbHeaderSize + GlbChunkHeaderSize + json_length > size)+ if (json_length > size - GlbHeaderSize - GlbChunkHeaderSize) { return cgltf_result_data_too_short; }@@ -1158,7 +1171,7 @@ const void* bin = NULL; cgltf_size bin_size = 0; - if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize <= size)+ if (GlbChunkHeaderSize <= size - GlbHeaderSize - GlbChunkHeaderSize - json_length) { // We can read another chunk const uint8_t* bin_chunk = json_chunk + json_length;@@ -1166,7 +1179,7 @@ // Bin chunk: length uint32_t bin_length; memcpy(&bin_length, bin_chunk, 4);- if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize + bin_length > size)+ if (bin_length > size - GlbHeaderSize - GlbChunkHeaderSize - json_length - GlbChunkHeaderSize) { return cgltf_result_data_too_short; }@@ -1552,6 +1565,9 @@ { cgltf_accessor* accessor = &data->accessors[i]; + CGLTF_ASSERT_IF(data->accessors[i].component_type == cgltf_component_type_invalid, cgltf_result_invalid_gltf);+ CGLTF_ASSERT_IF(data->accessors[i].type == cgltf_type_invalid, cgltf_result_invalid_gltf);+ cgltf_size element_size = cgltf_calc_size(accessor->type, accessor->component_type); if (accessor->buffer_view)@@ -1565,7 +1581,7 @@ { cgltf_accessor_sparse* sparse = &accessor->sparse; - cgltf_size indices_component_size = cgltf_calc_size(cgltf_type_scalar, sparse->indices_component_type);+ cgltf_size indices_component_size = cgltf_component_size(sparse->indices_component_type); cgltf_size indices_req_size = sparse->indices_byte_offset + indices_component_size * sparse->count; cgltf_size values_req_size = sparse->values_byte_offset + element_size * sparse->count; @@ -1631,43 +1647,48 @@ for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j) {+ CGLTF_ASSERT_IF(data->meshes[i].primitives[j].type == cgltf_primitive_type_invalid, cgltf_result_invalid_gltf); CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets_count != data->meshes[i].primitives[0].targets_count, cgltf_result_invalid_gltf); - if (data->meshes[i].primitives[j].attributes_count)+ CGLTF_ASSERT_IF(data->meshes[i].primitives[j].attributes_count == 0, cgltf_result_invalid_gltf);++ cgltf_accessor* first = data->meshes[i].primitives[j].attributes[0].data;++ CGLTF_ASSERT_IF(first->count == 0, cgltf_result_invalid_gltf);++ for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k) {- cgltf_accessor* first = data->meshes[i].primitives[j].attributes[0].data;+ CGLTF_ASSERT_IF(data->meshes[i].primitives[j].attributes[k].data->count != first->count, cgltf_result_invalid_gltf);+ } - for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)+ for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)+ {+ for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m) {- CGLTF_ASSERT_IF(data->meshes[i].primitives[j].attributes[k].data->count != first->count, cgltf_result_invalid_gltf);+ CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets[k].attributes[m].data->count != first->count, cgltf_result_invalid_gltf); }+ } - for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)- {- for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)- {- CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets[k].attributes[m].data->count != first->count, cgltf_result_invalid_gltf);- }- }+ cgltf_accessor* indices = data->meshes[i].primitives[j].indices; - cgltf_accessor* indices = data->meshes[i].primitives[j].indices;+ CGLTF_ASSERT_IF(indices &&+ indices->component_type != cgltf_component_type_r_8u &&+ indices->component_type != cgltf_component_type_r_16u &&+ indices->component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf); - CGLTF_ASSERT_IF(indices &&- indices->component_type != cgltf_component_type_r_8u &&- indices->component_type != cgltf_component_type_r_16u &&- indices->component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf);+ CGLTF_ASSERT_IF(indices && indices->type != cgltf_type_scalar, cgltf_result_invalid_gltf);+ CGLTF_ASSERT_IF(indices && indices->stride != cgltf_component_size(indices->component_type), cgltf_result_invalid_gltf); - if (indices && indices->buffer_view && indices->buffer_view->buffer->data)- {- cgltf_size index_bound = cgltf_calc_index_bound(indices->buffer_view, indices->offset, indices->component_type, indices->count);+ if (indices && indices->buffer_view && indices->buffer_view->buffer->data)+ {+ cgltf_size index_bound = cgltf_calc_index_bound(indices->buffer_view, indices->offset, indices->component_type, indices->count); - CGLTF_ASSERT_IF(index_bound >= first->count, cgltf_result_data_too_short);- }+ CGLTF_ASSERT_IF(index_bound >= first->count, cgltf_result_data_too_short);+ } - for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k)- {- CGLTF_ASSERT_IF(data->meshes[i].primitives[j].mappings[k].variant >= data->variants_count, cgltf_result_invalid_gltf);- }+ for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k)+ {+ CGLTF_ASSERT_IF(data->meshes[i].primitives[j].mappings[k].variant >= data->variants_count, cgltf_result_invalid_gltf); } } }@@ -1724,10 +1745,15 @@ cgltf_size values = channel->sampler->interpolation == cgltf_interpolation_type_cubic_spline ? 3 : 1; - CGLTF_ASSERT_IF(channel->sampler->input->count * components * values != channel->sampler->output->count, cgltf_result_data_too_short);+ CGLTF_ASSERT_IF(channel->sampler->input->count * components * values != channel->sampler->output->count, cgltf_result_invalid_gltf); } } + for (cgltf_size i = 0; i < data->variants_count; ++i)+ {+ CGLTF_ASSERT_IF(!data->variants[i].name, cgltf_result_invalid_gltf);+ }+ return cgltf_result_success; } @@ -1902,7 +1928,7 @@ data->memory.free_func(data->memory.user_data, data->materials); - for (cgltf_size i = 0; i < data->images_count; ++i) + for (cgltf_size i = 0; i < data->images_count; ++i) { data->memory.free_func(data->memory.user_data, data->images[i].name); data->memory.free_func(data->memory.user_data, data->images[i].uri);@@ -2550,7 +2576,7 @@ return (cgltf_size)(object - animation->channels); } -cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_uint* out, cgltf_size index_count)+cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* out, cgltf_size out_component_size, cgltf_size index_count) { if (out == NULL) {@@ -2558,6 +2584,7 @@ } index_count = accessor->count < index_count ? accessor->count : index_count;+ cgltf_size index_component_size = cgltf_component_size(accessor->component_type); if (accessor->is_sparse) {@@ -2567,6 +2594,10 @@ { return 0; }+ if (index_component_size > out_component_size)+ {+ return 0;+ } const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view); if (element == NULL) {@@ -2574,18 +2605,29 @@ } element += accessor->offset; - if (accessor->component_type == cgltf_component_type_r_32u && accessor->stride == sizeof(cgltf_uint))+ if (index_component_size == out_component_size && accessor->stride == out_component_size) {- memcpy(out, element, index_count * sizeof(cgltf_uint));+ memcpy(out, element, index_count * index_component_size);+ return index_count; }- else- {- cgltf_uint* dest = out; - for (cgltf_size index = 0; index < index_count; index++, dest++, element += accessor->stride)+ // The component size of the output array is larger than the component size of the index data, so index data will be padded.+ switch (out_component_size)+ {+ case 2:+ for (cgltf_size index = 0; index < index_count; index++, element += accessor->stride) {- *dest = (cgltf_uint)cgltf_component_read_index(element, accessor->component_type);+ ((uint16_t*)out)[index] = (uint16_t)cgltf_component_read_index(element, accessor->component_type); }+ break;+ case 4:+ for (cgltf_size index = 0; index < index_count; index++, element += accessor->stride)+ {+ ((uint32_t*)out)[index] = (uint32_t)cgltf_component_read_index(element, accessor->component_type);+ }+ break;+ default:+ break; } return index_count;@@ -2596,7 +2638,7 @@ #define CGLTF_ERROR_LEGACY -3 #define CGLTF_CHECK_TOKTYPE(tok_, type_) if ((tok_).type != (type_)) { return CGLTF_ERROR_JSON; }-#define CGLTF_CHECK_TOKTYPE_RETTYPE(tok_, type_, ret_) if ((tok_).type != (type_)) { return (ret_)CGLTF_ERROR_JSON; }+#define CGLTF_CHECK_TOKTYPE_RET(tok_, type_, ret_) if ((tok_).type != (type_)) { return ret_; } #define CGLTF_CHECK_KEY(tok_) if ((tok_).type != JSMN_STRING || (tok_).size == 0) { return CGLTF_ERROR_JSON; } /* checking size for 0 verifies that a value follows the key */ #define CGLTF_PTRINDEX(type, idx) (type*)((cgltf_size)idx + 1)@@ -2623,12 +2665,13 @@ static cgltf_size cgltf_json_to_size(jsmntok_t const* tok, const uint8_t* json_chunk) {- CGLTF_CHECK_TOKTYPE_RETTYPE(*tok, JSMN_PRIMITIVE, cgltf_size);+ CGLTF_CHECK_TOKTYPE_RET(*tok, JSMN_PRIMITIVE, 0); char tmp[128]; int size = (size_t)(tok->end - tok->start) < sizeof(tmp) ? (int)(tok->end - tok->start) : (int)(sizeof(tmp) - 1); strncpy(tmp, (const char*)json_chunk + tok->start, size); tmp[size] = 0;- return (cgltf_size)CGLTF_ATOLL(tmp);+ long long res = CGLTF_ATOLL(tmp);+ return res < 0 ? 0 : (cgltf_size)res; } static cgltf_float cgltf_json_to_float(jsmntok_t const* tok, const uint8_t* json_chunk)@@ -2810,6 +2853,11 @@ if (us && *out_type != cgltf_attribute_type_invalid) { *out_index = CGLTF_ATOI(us + 1);+ if (*out_index < 0)+ {+ *out_type = cgltf_attribute_type_invalid;+ *out_index = 0;+ } } } @@ -3142,6 +3190,31 @@ return i; } +static cgltf_primitive_type cgltf_json_to_primitive_type(jsmntok_t const* tok, const uint8_t* json_chunk)+{+ int type = cgltf_json_to_int(tok, json_chunk);++ switch (type)+ {+ case 0:+ return cgltf_primitive_type_points;+ case 1:+ return cgltf_primitive_type_lines;+ case 2:+ return cgltf_primitive_type_line_loop;+ case 3:+ return cgltf_primitive_type_line_strip;+ case 4:+ return cgltf_primitive_type_triangles;+ case 5:+ return cgltf_primitive_type_triangle_strip;+ case 6:+ return cgltf_primitive_type_triangle_fan;+ default:+ return cgltf_primitive_type_invalid;+ }+}+ static int cgltf_parse_json_primitive(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_primitive* out_prim) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);@@ -3158,9 +3231,7 @@ if (cgltf_json_strcmp(tokens+i, json_chunk, "mode") == 0) { ++i;- out_prim->type- = (cgltf_primitive_type)- cgltf_json_to_int(tokens+i, json_chunk);+ out_prim->type = cgltf_json_to_primitive_type(tokens+i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "indices") == 0)@@ -3410,7 +3481,7 @@ if (cgltf_json_strcmp(tokens+i, json_chunk, "count") == 0) { ++i;- out_sparse->count = cgltf_json_to_int(tokens + i, json_chunk);+ out_sparse->count = cgltf_json_to_size(tokens + i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "indices") == 0)@@ -3546,8 +3617,7 @@ else if (cgltf_json_strcmp(tokens+i, json_chunk, "count") == 0) { ++i;- out_accessor->count =- cgltf_json_to_int(tokens+i, json_chunk);+ out_accessor->count = cgltf_json_to_size(tokens+i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "type") == 0)@@ -3700,7 +3770,7 @@ out_texture_view->texcoord = cgltf_json_to_int(tokens + i, json_chunk); ++i; }- else if (cgltf_json_strcmp(tokens + i, json_chunk, "scale") == 0) + else if (cgltf_json_strcmp(tokens + i, json_chunk, "scale") == 0) { ++i; out_texture_view->scale = cgltf_json_to_float(tokens + i, json_chunk);@@ -3769,11 +3839,11 @@ if (cgltf_json_strcmp(tokens+i, json_chunk, "metallicFactor") == 0) { ++i;- out_pbr->metallic_factor = + out_pbr->metallic_factor = cgltf_json_to_float(tokens + i, json_chunk); ++i; }- else if (cgltf_json_strcmp(tokens+i, json_chunk, "roughnessFactor") == 0) + else if (cgltf_json_strcmp(tokens+i, json_chunk, "roughnessFactor") == 0) { ++i; out_pbr->roughness_factor =@@ -4234,6 +4304,37 @@ return i; } +static int cgltf_parse_json_dispersion(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_dispersion* out_dispersion)+{+ CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);+ int size = tokens[i].size;+ ++i;+++ for (int j = 0; j < size; ++j)+ {+ CGLTF_CHECK_KEY(tokens[i]);++ if (cgltf_json_strcmp(tokens + i, json_chunk, "dispersion") == 0)+ {+ ++i;+ out_dispersion->dispersion = cgltf_json_to_float(tokens + i, json_chunk);+ ++i;+ }+ else+ {+ i = cgltf_skip_json(tokens, i + 1);+ }++ if (i < 0)+ {+ return i;+ }+ }++ return i;+}+ static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_image* out_image) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);@@ -4241,11 +4342,11 @@ int size = tokens[i].size; ++i; - for (int j = 0; j < size; ++j) + for (int j = 0; j < size; ++j) { CGLTF_CHECK_KEY(tokens[i]); - if (cgltf_json_strcmp(tokens + i, json_chunk, "uri") == 0) + if (cgltf_json_strcmp(tokens + i, json_chunk, "uri") == 0) { i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_image->uri); }@@ -4325,7 +4426,7 @@ = cgltf_json_to_int(tokens + i, json_chunk); ++i; }- else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapT") == 0) + else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapT") == 0) { ++i; out_sampler->wrap_t@@ -4375,7 +4476,7 @@ out_texture->sampler = CGLTF_PTRINDEX(cgltf_sampler, cgltf_json_to_int(tokens + i, json_chunk)); ++i; }- else if (cgltf_json_strcmp(tokens + i, json_chunk, "source") == 0) + else if (cgltf_json_strcmp(tokens + i, json_chunk, "source") == 0) { ++i; out_texture->image = CGLTF_PTRINDEX(cgltf_image, cgltf_json_to_int(tokens + i, json_chunk));@@ -4627,6 +4728,11 @@ out_material->has_anisotropy = 1; i = cgltf_parse_json_anisotropy(options, tokens, i + 1, json_chunk, &out_material->anisotropy); }+ else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_dispersion") == 0)+ {+ out_material->has_dispersion = 1;+ i = cgltf_parse_json_dispersion(tokens, i + 1, json_chunk, &out_material->dispersion);+ } else { i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_material->extensions[out_material->extensions_count++]));@@ -4786,7 +4892,7 @@ else if (cgltf_json_strcmp(tokens+i, json_chunk, "count") == 0) { ++i;- out_meshopt_compression->count = cgltf_json_to_int(tokens+i, json_chunk);+ out_meshopt_compression->count = cgltf_json_to_size(tokens+i, json_chunk); ++i; } else if (cgltf_json_strcmp(tokens+i, json_chunk, "mode") == 0)
− raylib/src/external/glfw/deps/vs2008/stdint.h
@@ -1,247 +0,0 @@-// ISO C9x compliant stdint.h for Microsoft Visual Studio-// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2008 Alexander Chemeris-// -// Redistribution and use in source and binary forms, with or without-// modification, are permitted provided that the following conditions are met:-// -// 1. Redistributions of source code must retain the above copyright notice,-// this list of conditions and the following disclaimer.-// -// 2. Redistributions in binary form must reproduce the above copyright-// notice, this list of conditions and the following disclaimer in the-// documentation and/or other materials provided with the distribution.-// -// 3. The name of the author may be used to endorse or promote products-// derived from this software without specific prior written permission.-// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.-// -///////////////////////////////////////////////////////////////////////////////--#ifndef _MSC_VER // [-#error "Use this header only with Microsoft Visual C++ compilers!"-#endif // _MSC_VER ]--#ifndef _MSC_STDINT_H_ // [-#define _MSC_STDINT_H_--#if _MSC_VER > 1000-#pragma once-#endif--#include <limits.h>--// For Visual Studio 6 in C++ mode and for many Visual Studio versions when-// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'-// or compiler give many errors like this:-// error C2733: second C linkage of overloaded function 'wmemchr' not allowed-#ifdef __cplusplus-extern "C" {-#endif-# include <wchar.h>-#ifdef __cplusplus-}-#endif--// Define _W64 macros to mark types changing their size, like intptr_t.-#ifndef _W64-# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300-# define _W64 __w64-# else-# define _W64-# endif-#endif---// 7.18.1 Integer types--// 7.18.1.1 Exact-width integer types--// Visual Studio 6 and Embedded Visual C++ 4 doesn't-// realize that, e.g. char has the same size as __int8-// so we give up on __intX for them.-#if (_MSC_VER < 1300)- typedef signed char int8_t;- typedef signed short int16_t;- typedef signed int int32_t;- typedef unsigned char uint8_t;- typedef unsigned short uint16_t;- typedef unsigned int uint32_t;-#else- typedef signed __int8 int8_t;- typedef signed __int16 int16_t;- typedef signed __int32 int32_t;- typedef unsigned __int8 uint8_t;- typedef unsigned __int16 uint16_t;- typedef unsigned __int32 uint32_t;-#endif-typedef signed __int64 int64_t;-typedef unsigned __int64 uint64_t;---// 7.18.1.2 Minimum-width integer types-typedef int8_t int_least8_t;-typedef int16_t int_least16_t;-typedef int32_t int_least32_t;-typedef int64_t int_least64_t;-typedef uint8_t uint_least8_t;-typedef uint16_t uint_least16_t;-typedef uint32_t uint_least32_t;-typedef uint64_t uint_least64_t;--// 7.18.1.3 Fastest minimum-width integer types-typedef int8_t int_fast8_t;-typedef int16_t int_fast16_t;-typedef int32_t int_fast32_t;-typedef int64_t int_fast64_t;-typedef uint8_t uint_fast8_t;-typedef uint16_t uint_fast16_t;-typedef uint32_t uint_fast32_t;-typedef uint64_t uint_fast64_t;--// 7.18.1.4 Integer types capable of holding object pointers-#ifdef _WIN64 // [- typedef signed __int64 intptr_t;- typedef unsigned __int64 uintptr_t;-#else // _WIN64 ][- typedef _W64 signed int intptr_t;- typedef _W64 unsigned int uintptr_t;-#endif // _WIN64 ]--// 7.18.1.5 Greatest-width integer types-typedef int64_t intmax_t;-typedef uint64_t uintmax_t;---// 7.18.2 Limits of specified-width integer types--#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259--// 7.18.2.1 Limits of exact-width integer types-#define INT8_MIN ((int8_t)_I8_MIN)-#define INT8_MAX _I8_MAX-#define INT16_MIN ((int16_t)_I16_MIN)-#define INT16_MAX _I16_MAX-#define INT32_MIN ((int32_t)_I32_MIN)-#define INT32_MAX _I32_MAX-#define INT64_MIN ((int64_t)_I64_MIN)-#define INT64_MAX _I64_MAX-#define UINT8_MAX _UI8_MAX-#define UINT16_MAX _UI16_MAX-#define UINT32_MAX _UI32_MAX-#define UINT64_MAX _UI64_MAX--// 7.18.2.2 Limits of minimum-width integer types-#define INT_LEAST8_MIN INT8_MIN-#define INT_LEAST8_MAX INT8_MAX-#define INT_LEAST16_MIN INT16_MIN-#define INT_LEAST16_MAX INT16_MAX-#define INT_LEAST32_MIN INT32_MIN-#define INT_LEAST32_MAX INT32_MAX-#define INT_LEAST64_MIN INT64_MIN-#define INT_LEAST64_MAX INT64_MAX-#define UINT_LEAST8_MAX UINT8_MAX-#define UINT_LEAST16_MAX UINT16_MAX-#define UINT_LEAST32_MAX UINT32_MAX-#define UINT_LEAST64_MAX UINT64_MAX--// 7.18.2.3 Limits of fastest minimum-width integer types-#define INT_FAST8_MIN INT8_MIN-#define INT_FAST8_MAX INT8_MAX-#define INT_FAST16_MIN INT16_MIN-#define INT_FAST16_MAX INT16_MAX-#define INT_FAST32_MIN INT32_MIN-#define INT_FAST32_MAX INT32_MAX-#define INT_FAST64_MIN INT64_MIN-#define INT_FAST64_MAX INT64_MAX-#define UINT_FAST8_MAX UINT8_MAX-#define UINT_FAST16_MAX UINT16_MAX-#define UINT_FAST32_MAX UINT32_MAX-#define UINT_FAST64_MAX UINT64_MAX--// 7.18.2.4 Limits of integer types capable of holding object pointers-#ifdef _WIN64 // [-# define INTPTR_MIN INT64_MIN-# define INTPTR_MAX INT64_MAX-# define UINTPTR_MAX UINT64_MAX-#else // _WIN64 ][-# define INTPTR_MIN INT32_MIN-# define INTPTR_MAX INT32_MAX-# define UINTPTR_MAX UINT32_MAX-#endif // _WIN64 ]--// 7.18.2.5 Limits of greatest-width integer types-#define INTMAX_MIN INT64_MIN-#define INTMAX_MAX INT64_MAX-#define UINTMAX_MAX UINT64_MAX--// 7.18.3 Limits of other integer types--#ifdef _WIN64 // [-# define PTRDIFF_MIN _I64_MIN-# define PTRDIFF_MAX _I64_MAX-#else // _WIN64 ][-# define PTRDIFF_MIN _I32_MIN-# define PTRDIFF_MAX _I32_MAX-#endif // _WIN64 ]--#define SIG_ATOMIC_MIN INT_MIN-#define SIG_ATOMIC_MAX INT_MAX--#ifndef SIZE_MAX // [-# ifdef _WIN64 // [-# define SIZE_MAX _UI64_MAX-# else // _WIN64 ][-# define SIZE_MAX _UI32_MAX-# endif // _WIN64 ]-#endif // SIZE_MAX ]--// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>-#ifndef WCHAR_MIN // [-# define WCHAR_MIN 0-#endif // WCHAR_MIN ]-#ifndef WCHAR_MAX // [-# define WCHAR_MAX _UI16_MAX-#endif // WCHAR_MAX ]--#define WINT_MIN 0-#define WINT_MAX _UI16_MAX--#endif // __STDC_LIMIT_MACROS ]---// 7.18.4 Limits of other integer types--#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260--// 7.18.4.1 Macros for minimum-width integer constants--#define INT8_C(val) val##i8-#define INT16_C(val) val##i16-#define INT32_C(val) val##i32-#define INT64_C(val) val##i64--#define UINT8_C(val) val##ui8-#define UINT16_C(val) val##ui16-#define UINT32_C(val) val##ui32-#define UINT64_C(val) val##ui64--// 7.18.4.2 Macros for greatest-width integer constants-#define INTMAX_C INT64_C-#define UINTMAX_C UINT64_C--#endif // __STDC_CONSTANT_MACROS ]---#endif // _MSC_STDINT_H_ ]
raylib/src/external/glfw/include/GLFW/glfw3.h view
@@ -361,10 +361,15 @@ #define GLFW_HAT_RIGHT_DOWN (GLFW_HAT_RIGHT | GLFW_HAT_DOWN) #define GLFW_HAT_LEFT_UP (GLFW_HAT_LEFT | GLFW_HAT_UP) #define GLFW_HAT_LEFT_DOWN (GLFW_HAT_LEFT | GLFW_HAT_DOWN)++/*! @ingroup input+ */+#define GLFW_KEY_UNKNOWN -1+ /*! @} */ -/*! @defgroup keys Keyboard keys- * @brief Keyboard key IDs.+/*! @defgroup keys Keyboard key tokens+ * @brief Keyboard key tokens. * * See [key input](@ref input_key) for how these are used. *@@ -387,9 +392,6 @@ * @{ */ -/* The unknown key */-#define GLFW_KEY_UNKNOWN -1- /* Printable keys */ #define GLFW_KEY_SPACE 32 #define GLFW_KEY_APOSTROPHE 39 /* ' */@@ -825,11 +827,11 @@ #define GLFW_FEATURE_UNIMPLEMENTED 0x0001000D /*! @brief Platform unavailable or no matching platform was found. *- * If emitted during initialization, no matching platform was found. If @ref- * GLFW_PLATFORM is set to `GLFW_ANY_PLATFORM`, GLFW could not detect any of the- * platforms supported by this library binary, except for the Null platform. If set to- * a specific platform, it is either not supported by this library binary or GLFW was not- * able to detect it.+ * If emitted during initialization, no matching platform was found. If the @ref+ * GLFW_PLATFORM init hint was set to `GLFW_ANY_PLATFORM`, GLFW could not detect any of+ * the platforms supported by this library binary, except for the Null platform. If the+ * init hint was set to a specific platform, it is either not supported by this library+ * binary or GLFW was not able to detect it. * * If emitted by a native access function, GLFW was initialized for a different platform * than the function is for.@@ -1096,9 +1098,16 @@ * [window hint](@ref GLFW_SCALE_TO_MONITOR). */ #define GLFW_SCALE_TO_MONITOR 0x0002200C-/*! @brief macOS specific- * [window hint](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint).+/*! @brief Window framebuffer scaling+ * [window hint](@ref GLFW_SCALE_FRAMEBUFFER_hint). */+#define GLFW_SCALE_FRAMEBUFFER 0x0002200D+/*! @brief Legacy name for compatibility.+ *+ * This is an alias for the+ * [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) window hint for+ * compatibility with earlier versions.+ */ #define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001 /*! @brief macOS specific * [window hint](@ref GLFW_COCOA_FRAME_NAME_hint).@@ -1117,6 +1126,9 @@ */ #define GLFW_X11_INSTANCE_NAME 0x00024002 #define GLFW_WIN32_KEYBOARD_MENU 0x00025001+/*! @brief Win32 specific [window hint](@ref GLFW_WIN32_SHOWDEFAULT_hint).+ */+#define GLFW_WIN32_SHOWDEFAULT 0x00025002 /*! @brief Wayland specific * [window hint](@ref GLFW_WAYLAND_APP_ID_hint). * @@ -1164,6 +1176,9 @@ #define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007 #define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008 +#define GLFW_WAYLAND_PREFER_LIBDECOR 0x00038001+#define GLFW_WAYLAND_DISABLE_LIBDECOR 0x00038002+ #define GLFW_ANY_POSITION 0x80000000 /*! @defgroup shapes Standard cursor shapes@@ -1215,11 +1230,11 @@ * @note @macos This shape is provided by a private system API and may fail * with @ref GLFW_CURSOR_UNAVAILABLE in the future. *- * @note @x11 This shape is provided by a newer standard not supported by all- * cursor themes.- * * @note @wayland This shape is provided by a newer standard not supported by * all cursor themes.+ *+ * @note @x11 This shape is provided by a newer standard not supported by all+ * cursor themes. */ #define GLFW_RESIZE_NWSE_CURSOR 0x00036007 /*! @brief The top-right to bottom-left diagonal resize/move arrow shape.@@ -1230,11 +1245,11 @@ * @note @macos This shape is provided by a private system API and may fail * with @ref GLFW_CURSOR_UNAVAILABLE in the future. *- * @note @x11 This shape is provided by a newer standard not supported by all- * cursor themes.- * * @note @wayland This shape is provided by a newer standard not supported by * all cursor themes.+ *+ * @note @x11 This shape is provided by a newer standard not supported by all+ * cursor themes. */ #define GLFW_RESIZE_NESW_CURSOR 0x00036008 /*! @brief The omni-directional resize/move cursor shape.@@ -1248,11 +1263,11 @@ * The operation-not-allowed shape. This is usually a circle with a diagonal * line through it. *- * @note @x11 This shape is provided by a newer standard not supported by all- * cursor themes.- * * @note @wayland This shape is provided by a newer standard not supported by * all cursor themes.+ *+ * @note @x11 This shape is provided by a newer standard not supported by all+ * cursor themes. */ #define GLFW_NOT_ALLOWED_CURSOR 0x0003600A /*! @brief Legacy name for compatibility.@@ -1307,6 +1322,11 @@ * X11 specific [init hint](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint). */ #define GLFW_X11_XCB_VULKAN_SURFACE 0x00052001+/*! @brief Wayland specific init hint.+ *+ * Wayland specific [init hint](@ref GLFW_WAYLAND_LIBDECOR_hint).+ */+#define GLFW_WAYLAND_LIBDECOR 0x00053001 /*! @} */ /*! @addtogroup init@@ -1406,16 +1426,25 @@ * or `NULL` if allocation failed. Note that not all parts of GLFW handle allocation * failures gracefully yet. *- * This function may be called during @ref glfwInit but before the library is- * flagged as initialized, as well as during @ref glfwTerminate after the- * library is no longer flagged as initialized.+ * This function must support being called during @ref glfwInit but before the library is+ * flagged as initialized, as well as during @ref glfwTerminate after the library is no+ * longer flagged as initialized. *- * Any memory allocated by this function will be deallocated during library- * termination or earlier.+ * Any memory allocated via this function will be deallocated via the same allocator+ * during library termination or earlier. *+ * Any memory allocated via this function must be suitably aligned for any object type.+ * If you are using C99 or earlier, this alignment is platform-dependent but will be the+ * same as what `malloc` provides. If you are using C11 or later, this is the value of+ * `alignof(max_align_t)`.+ * * The size will always be greater than zero. Allocations of size zero are filtered out * before reaching the custom allocator. *+ * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY.+ *+ * This function must not call any GLFW function.+ * * @param[in] size The minimum size, in bytes, of the memory block. * @param[in] user The user-defined pointer from the allocator. * @return The address of the newly allocated memory block, or `NULL` if an@@ -1426,7 +1455,8 @@ * * @reentrancy This function should not call any GLFW function. *- * @thread_safety This function may be called from any thread that calls GLFW functions.+ * @thread_safety This function must support being called from any thread that calls GLFW+ * functions. * * @sa @ref init_allocator * @sa @ref GLFWallocator@@ -1449,17 +1479,27 @@ * `NULL` if allocation failed. Note that not all parts of GLFW handle allocation * failures gracefully yet. *- * This function may be called during @ref glfwInit but before the library is- * flagged as initialized, as well as during @ref glfwTerminate after the- * library is no longer flagged as initialized.+ * This function must support being called during @ref glfwInit but before the library is+ * flagged as initialized, as well as during @ref glfwTerminate after the library is no+ * longer flagged as initialized. *- * Any memory allocated by this function will be deallocated during library- * termination or earlier.+ * Any memory allocated via this function will be deallocated via the same allocator+ * during library termination or earlier. *+ * Any memory allocated via this function must be suitably aligned for any object type.+ * If you are using C99 or earlier, this alignment is platform-dependent but will be the+ * same as what `realloc` provides. If you are using C11 or later, this is the value of+ * `alignof(max_align_t)`.+ * * The block address will never be `NULL` and the size will always be greater than zero.- * Reallocations of a block to size zero are converted into deallocations. Reallocations- * of `NULL` to a non-zero size are converted into regular allocations.+ * Reallocations of a block to size zero are converted into deallocations before reaching+ * the custom allocator. Reallocations of `NULL` to a non-zero size are converted into+ * regular allocations before reaching the custom allocator. *+ * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY.+ *+ * This function must not call any GLFW function.+ * * @param[in] block The address of the memory block to reallocate. * @param[in] size The new minimum size, in bytes, of the memory block. * @param[in] user The user-defined pointer from the allocator.@@ -1471,7 +1511,8 @@ * * @reentrancy This function should not call any GLFW function. *- * @thread_safety This function may be called from any thread that calls GLFW functions.+ * @thread_safety This function must support being called from any thread that calls GLFW+ * functions. * * @sa @ref init_allocator * @sa @ref GLFWallocator@@ -1493,13 +1534,17 @@ * This function may deallocate the specified memory block. This memory block * will have been allocated with the same allocator. *- * This function may be called during @ref glfwInit but before the library is- * flagged as initialized, as well as during @ref glfwTerminate after the- * library is no longer flagged as initialized.+ * This function must support being called during @ref glfwInit but before the library is+ * flagged as initialized, as well as during @ref glfwTerminate after the library is no+ * longer flagged as initialized. * * The block address will never be `NULL`. Deallocations of `NULL` are filtered out * before reaching the custom allocator. *+ * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY.+ *+ * This function must not call any GLFW function.+ * * @param[in] block The address of the memory block to deallocate. * @param[in] user The user-defined pointer from the allocator. *@@ -1508,7 +1553,8 @@ * * @reentrancy This function should not call any GLFW function. *- * @thread_safety This function may be called from any thread that calls GLFW functions.+ * @thread_safety This function must support being called from any thread that calls GLFW+ * functions. * * @sa @ref init_allocator * @sa @ref GLFWallocator@@ -2076,8 +2122,11 @@ float axes[6]; } GLFWgamepadstate; -/*! @brief+/*! @brief Custom heap memory allocator. *+ * This describes a custom heap memory allocator for GLFW. To set an allocator, pass it+ * to @ref glfwInitAllocator before initializing the library.+ * * @sa @ref init_allocator * @sa @ref glfwInitAllocator *@@ -2087,9 +2136,21 @@ */ typedef struct GLFWallocator {+ /*! The memory allocation function. See @ref GLFWallocatefun for details about+ * allocation function.+ */ GLFWallocatefun allocate;+ /*! The memory reallocation function. See @ref GLFWreallocatefun for details about+ * reallocation function.+ */ GLFWreallocatefun reallocate;+ /*! The memory deallocation function. See @ref GLFWdeallocatefun for details about+ * deallocation function.+ */ GLFWdeallocatefun deallocate;+ /*! The user pointer for this custom allocator. This value will be passed to the+ * allocator functions.+ */ void* user; } GLFWallocator; @@ -2134,6 +2195,13 @@ * and dock icon can be disabled entirely with the @ref GLFW_COCOA_MENUBAR init * hint. *+ * @remark __Wayland, X11:__ If the library was compiled with support for both+ * Wayland and X11, and the @ref GLFW_PLATFORM init hint is set to+ * `GLFW_ANY_PLATFORM`, the `XDG_SESSION_TYPE` environment variable affects+ * which platform is picked. If the environment variable is not set, or is set+ * to something other than `wayland` or `x11`, the regular detection mechanism+ * will be used instead.+ * * @remark @x11 This function will set the `LC_CTYPE` category of the * application locale according to the current environment if that category is * still "C". This is because the "C" locale breaks Unicode text input.@@ -2222,9 +2290,13 @@ * To use the default allocator, call this function with a `NULL` argument. * * If you specify an allocator struct, every member must be a valid function- * pointer. If any member is `NULL`, this function emits @ref- * GLFW_INVALID_VALUE and the init allocator is unchanged.+ * pointer. If any member is `NULL`, this function will emit @ref+ * GLFW_INVALID_VALUE and the init allocator will be unchanged. *+ * The functions in the allocator must fulfil a number of requirements. See the+ * documentation for @ref GLFWallocatefun, @ref GLFWreallocatefun and @ref+ * GLFWdeallocatefun for details.+ * * @param[in] allocator The allocator to use at the next initialization, or * `NULL` to use the default one. *@@ -2590,10 +2662,11 @@ * specified monitor. * * Some platforms do not provide accurate monitor size information, either- * because the monitor- * [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data)- * data is incorrect or because the driver does not report it accurately.+ * because the monitor [EDID][] data is incorrect or because the driver does+ * not report it accurately. *+ * [EDID]: https://en.wikipedia.org/wiki/Extended_display_identification_data+ * * Any or all of the size arguments may be `NULL`. If an error occurs, all * non-`NULL` size arguments will be set to zero. *@@ -2639,6 +2712,9 @@ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. *+ * @remark @wayland Fractional scaling information is not yet available for+ * monitors, so this function only returns integer content scales.+ * * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_scale@@ -2835,11 +2911,11 @@ * @param[in] monitor The monitor whose gamma ramp to set. * @param[in] gamma The desired exponent. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref- * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_INVALID_VALUE,+ * @ref GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * * @remark @wayland Gamma handling is a privileged protocol, this function- * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR.+ * will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE. * * @thread_safety This function must only be called from the main thread. *@@ -2859,11 +2935,11 @@ * @return The current gamma ramp, or `NULL` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref- * GLFW_PLATFORM_ERROR.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR+ * and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * * @remark @wayland Gamma handling is a privileged protocol, this function- * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR while+ * will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE while * returning `NULL`. * * @pointer_lifetime The returned structure and its arrays are allocated and@@ -2898,8 +2974,8 @@ * @param[in] monitor The monitor whose gamma ramp to set. * @param[in] ramp The gamma ramp to use. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref- * GLFW_PLATFORM_ERROR.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR+ * and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * * @remark The size of the specified gamma ramp should match the size of the * current ramp for that monitor.@@ -2907,7 +2983,7 @@ * @remark @win32 The gamma ramp size must be 256. * * @remark @wayland Gamma handling is a privileged protocol, this function- * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR.+ * will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE. * * @pointer_lifetime The specified gamma ramp is copied before this function * returns.@@ -3079,8 +3155,8 @@ * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref- * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref- * GLFW_PLATFORM_ERROR.+ * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE, @ref+ * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. * * @remark @win32 Window creation will fail if the Microsoft GDI software * OpenGL implementation is the only one available.@@ -3102,23 +3178,35 @@ * @remark @macos The GLFW window has no icon, as it is not a document * window, but the dock icon will be the same as the application bundle's icon. * For more information on bundles, see the- * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)- * in the Mac Developer Library.+ * [Bundle Programming Guide][bundle-guide] in the Mac Developer Library. *+ * [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/+ * * @remark @macos On OS X 10.10 and later the window frame will not be rendered * at full resolution on Retina displays unless the- * [GLFW_COCOA_RETINA_FRAMEBUFFER](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint)+ * [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) * hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the * application bundle's `Info.plist`. For more information, see- * [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html)- * in the Mac Developer Library. The GLFW test and example programs use- * a custom `Info.plist` template for this, which can be found as- * `CMake/Info.plist.in` in the source tree.+ * [High Resolution Guidelines for OS X][hidpi-guide] in the Mac Developer+ * Library. The GLFW test and example programs use a custom `Info.plist`+ * template for this, which can be found as `CMake/Info.plist.in` in the source+ * tree. *+ * [hidpi-guide]: https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html+ * * @remark @macos When activating frame autosaving with * [GLFW_COCOA_FRAME_NAME](@ref GLFW_COCOA_FRAME_NAME_hint), the specified * window size and position may be overridden by previously saved values. *+ * @remark @wayland GLFW uses [libdecor][] where available to create its window+ * decorations. This in turn uses server-side XDG decorations where available+ * and provides high quality client-side decorations on compositors like GNOME.+ * If both XDG decorations and libdecor are unavailable, GLFW falls back to+ * a very simple set of window decorations that only support moving, resizing+ * and the window manager's right-click menu.+ *+ * [libdecor]: https://gitlab.freedesktop.org/libdecor/libdecor+ * * @remark @x11 Some window managers will not respect the placement of * initially hidden windows. *@@ -3135,20 +3223,6 @@ * [GLFW_X11_INSTANCE_NAME](@ref GLFW_X11_INSTANCE_NAME_hint) window hints to * override this. *- * @remark @wayland Compositors should implement the xdg-decoration protocol- * for GLFW to decorate the window properly. If this protocol isn't- * supported, or if the compositor prefers client-side decorations, a very- * simple fallback frame will be drawn using the wp_viewporter protocol. A- * compositor can still emit close, maximize or fullscreen events, using for- * instance a keybind mechanism. If neither of these protocols is supported,- * the window won't be decorated.- *- * @remark @wayland A full screen window will not attempt to change the mode,- * no matter what the requested size or refresh rate.- *- * @remark @wayland Screensaver inhibition requires the idle-inhibit protocol- * to be implemented in the user's compositor.- * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_creation@@ -3231,6 +3305,38 @@ */ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value); +/*! @brief Returns the title of the specified window.+ *+ * This function returns the window title, encoded as UTF-8, of the specified+ * window. This is the title set previously by @ref glfwCreateWindow+ * or @ref glfwSetWindowTitle.+ *+ * @param[in] window The window to query.+ * @return The UTF-8 encoded window title, or `NULL` if an+ * [error](@ref error_handling) occurred.+ *+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ *+ * @remark The returned title is currently a copy of the title last set by @ref+ * glfwCreateWindow or @ref glfwSetWindowTitle. It does not include any+ * additional text which may be appended by the platform or another program.+ *+ * @pointer_lifetime The returned string is allocated and freed by GLFW. You+ * should not free it yourself. It is valid until the next call to @ref+ * glfwGetWindowTitle or @ref glfwSetWindowTitle, or until the library is+ * terminated.+ *+ * @thread_safety This function must only be called from the main thread.+ *+ * @sa @ref window_title+ * @sa @ref glfwSetWindowTitle+ *+ * @since Added in version 3.4.+ *+ * @ingroup window+ */+GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* window);+ /*! @brief Sets the title of the specified window. * * This function sets the window title, encoded as UTF-8, of the specified@@ -3248,6 +3354,7 @@ * @thread_safety This function must only be called from the main thread. * * @sa @ref window_title+ * @sa @ref glfwGetWindowTitle * * @since Added in version 1.0. * @glfw3 Added window handle parameter.@@ -3287,9 +3394,10 @@ * @remark @macos Regular windows do not have icons on macOS. This function * will emit @ref GLFW_FEATURE_UNAVAILABLE. The dock icon will be the same as * the application bundle's icon. For more information on bundles, see the- * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)- * in the Mac Developer Library.+ * [Bundle Programming Guide][bundle-guide] in the Mac Developer Library. *+ * [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/+ * * @remark @wayland There is no existing protocol to change an icon, the * window will thus inherit the one defined in the application's desktop file. * This function will emit @ref GLFW_FEATURE_UNAVAILABLE.@@ -3512,9 +3620,6 @@ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. *- * @remark @wayland A full screen window will not attempt to change the mode,- * no matter what the requested size.- * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size@@ -3846,11 +3951,11 @@ * * @param[in] window The window to give input focus. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref- * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_PLATFORM_ERROR. *- * @remark @wayland It is not possible for an application to set the input- * focus. This function will emit @ref GLFW_FEATURE_UNAVAILABLE.+ * @remark @wayland The compositor will likely ignore focus requests unless+ * another window created by the same application already has input focus. * * @thread_safety This function must only be called from the main thread. *@@ -3955,9 +4060,6 @@ * @remark @wayland The desired window position is ignored, as there is no way * for an application to set this property. *- * @remark @wayland Setting the window to full screen will not attempt to- * change the mode, no matter what the requested size or refresh rate.- * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_monitor@@ -4030,11 +4132,15 @@ * @param[in] value `GLFW_TRUE` or `GLFW_FALSE`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref- * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.+ * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_PLATFORM_ERROR and @ref+ * GLFW_FEATURE_UNAVAILABLE (see remarks). * * @remark Calling @ref glfwGetWindowAttrib will always return the latest * value, even if that value is ignored by the current mode of the window. *+ * @remark @wayland The [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) window attribute is+ * not supported. Setting this will emit @ref GLFW_FEATURE_UNAVAILABLE.+ * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_attribs@@ -4709,8 +4815,8 @@ * @param[in] scancode The scancode of the key to query. * @return The UTF-8 encoded, layout-specific name of the key, or `NULL`. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref- * GLFW_PLATFORM_ERROR.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ * GLFW_INVALID_VALUE, @ref GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * * @remark The contents of the returned string may change when a keyboard * layout change event is received.@@ -4732,15 +4838,18 @@ * * This function returns the platform-specific scancode of the specified key. *- * If the key is `GLFW_KEY_UNKNOWN` or does not exist on the keyboard this- * method will return `-1`.+ * If the specified [key token](@ref keys) corresponds to a physical key not+ * supported on the current platform then this method will return `-1`.+ * Calling this function with anything other than a key token will return `-1`+ * and generate a @ref GLFW_INVALID_ENUM error. *- * @param[in] key Any [named key](@ref keys).- * @return The platform-specific scancode for the key, or `-1` if an- * [error](@ref error_handling) occurred.+ * @param[in] key Any [key token](@ref keys).+ * @return The platform-specific scancode for the key, or `-1` if the key is+ * not supported on the current platform or an [error](@ref error_handling)+ * occurred. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_INVALID_ENUM. * * @thread_safety This function may be called from any thread. *@@ -4881,11 +4990,11 @@ * @param[in] ypos The desired y-coordinate, relative to the top edge of the * content area. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref- * GLFW_PLATFORM_ERROR.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * * @remark @wayland This function will only work when the cursor mode is- * `GLFW_CURSOR_DISABLED`, otherwise it will do nothing.+ * `GLFW_CURSOR_DISABLED`, otherwise it will emit @ref GLFW_FEATURE_UNAVAILABLE. * * @thread_safety This function must only be called from the main thread. *@@ -5049,9 +5158,9 @@ * [character callback](@ref glfwSetCharCallback) instead. * * When a window loses input focus, it will generate synthetic key release- * events for all pressed keys. You can tell these events from user-generated- * events by the fact that the synthetic ones are generated after the focus- * loss event has been processed, i.e. after the+ * events for all pressed keys with associated key tokens. You can tell these+ * events from user-generated events by the fact that the synthetic ones are+ * generated after the focus loss event has been processed, i.e. after the * [window focus callback](@ref glfwSetWindowFocusCallback) has been called. * * The scancode of a key is specific to that platform or sometimes even to that@@ -5332,8 +5441,6 @@ * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. *- * @remark @wayland File drop is currently unimplemented.- * * @thread_safety This function must only be called from the main thread. * * @sa @ref path_drop@@ -5800,6 +5907,11 @@ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. *+ * @remark @win32 The clipboard on Windows has a single global lock for reading and+ * writing. GLFW tries to acquire it a few times, which is almost always enough. If it+ * cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns.+ * It is safe to try this multiple times.+ * * @pointer_lifetime The specified string is copied before this function * returns. *@@ -5828,6 +5940,11 @@ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_FORMAT_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. *+ * @remark @win32 The clipboard on Windows has a single global lock for reading and+ * writing. GLFW tries to acquire it a few times, which is almost always enough. If it+ * cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns.+ * It is safe to try this multiple times.+ * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the next call to @ref * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library@@ -5950,13 +6067,16 @@ * thread. * * This function makes the OpenGL or OpenGL ES context of the specified window- * current on the calling thread. A context must only be made current on- * a single thread at a time and each thread can have only a single current- * context at a time.+ * current on the calling thread. It can also detach the current context from+ * the calling thread without making a new one current by passing in `NULL`. *- * When moving a context between threads, you must make it non-current on the- * old thread before making it current on the new one.+ * A context must only be made current on a single thread at a time and each+ * thread can have only a single current context at a time. Making a context+ * current detaches any previously current context on the calling thread. *+ * When moving a context between threads, you must detach it (make it+ * non-current) on the old thread before making it current on the new one.+ * * By default, making a context non-current implicitly forces a pipeline flush. * On machines that support `GL_KHR_context_flush_control`, you can control * whether a context performs this flush by setting the@@ -5969,6 +6089,10 @@ * * @param[in] window The window whose context to make current, or `NULL` to * detach the current context.+ *+ * @remarks If the previously current context was created via a different+ * context creation API than the one passed to this function, GLFW will still+ * detach the previous one from its API before making the new one current. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
raylib/src/external/glfw/include/GLFW/glfw3native.h view
@@ -169,7 +169,8 @@ * of the specified monitor, or `NULL` if an [error](@ref error_handling) * occurred. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -186,7 +187,8 @@ * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -202,7 +204,8 @@ * @return The `HWND` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_PLATFORM_UNAVAILABLE. * * @remark The `HDC` associated with the window can be queried with the * [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)@@ -228,8 +231,8 @@ * @return The `HGLRC` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref- * GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT. * * @remark The `HDC` associated with the window can be queried with the * [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)@@ -255,7 +258,8 @@ * @return The `CGDirectDisplayID` of the specified monitor, or * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -271,7 +275,8 @@ * @return The `NSWindow` of the specified window, or `nil` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -281,6 +286,23 @@ * @ingroup native */ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);++/*! @brief Returns the `NSView` of the specified window.+ *+ * @return The `NSView` of the specified window, or `nil` if an+ * [error](@ref error_handling) occurred.+ *+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_PLATFORM_UNAVAILABLE.+ *+ * @thread_safety This function may be called from any thread. Access is not+ * synchronized.+ *+ * @since Added in version 3.4.+ *+ * @ingroup native+ */+GLFWAPI id glfwGetCocoaView(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_NSGL)@@ -289,8 +311,8 @@ * @return The `NSOpenGLContext` of the specified window, or `nil` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref- * GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -308,7 +330,8 @@ * @return The `Display` used by GLFW, or `NULL` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -324,7 +347,8 @@ * @return The `RRCrtc` of the specified monitor, or `None` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -340,7 +364,8 @@ * @return The `RROutput` of the specified monitor, or `None` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -356,7 +381,8 @@ * @return The `Window` of the specified window, or `None` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -371,8 +397,8 @@ * * @param[in] string A UTF-8 encoded string. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref- * GLFW_PLATFORM_ERROR.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. * * @pointer_lifetime The specified string is copied before this function * returns.@@ -397,8 +423,8 @@ * @return The contents of the selection as a UTF-8 encoded string, or `NULL` * if an [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref- * GLFW_PLATFORM_ERROR.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the next call to @ref@@ -424,8 +450,8 @@ * @return The `GLXContext` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref- * GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -441,8 +467,8 @@ * @return The `GLXWindow` of the specified window, or `None` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref- * GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref+ * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -460,7 +486,8 @@ * @return The `struct wl_display*` used by GLFW, or `NULL` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -476,7 +503,8 @@ * @return The `struct wl_output*` of the specified monitor, or `NULL` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -492,7 +520,8 @@ * @return The main `struct wl_surface*` of the specified window, or `NULL` if * an [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_PLATFORM_UNAVAILABLE. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -529,8 +558,8 @@ * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref- * GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_NO_WINDOW_CONTEXT. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -546,8 +575,8 @@ * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref- * GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_NO_WINDOW_CONTEXT. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -572,8 +601,8 @@ * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref- * GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_NO_WINDOW_CONTEXT. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -596,8 +625,8 @@ * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref- * GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_NO_WINDOW_CONTEXT. * * @thread_safety This function may be called from any thread. Access is not * synchronized.@@ -613,8 +642,8 @@ * @return The `OSMesaContext` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. *- * @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref- * GLFW_NOT_INITIALIZED.+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref+ * GLFW_NO_WINDOW_CONTEXT. * * @thread_safety This function may be called from any thread. Access is not * synchronized.
raylib/src/external/glfw/src/cocoa_init.m view
@@ -1,7 +1,8 @@ //========================================================================-// GLFW 3.4 macOS - www.glfw.org+// GLFW 3.4 macOS (modified for raylib) - www.glfw.org; www.raylib.com //------------------------------------------------------------------------ // Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>+// Copyright (c) 2024 M374LX <wilsalx@gmail.com> // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages@@ -23,10 +24,11 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h"++#if defined(_GLFW_COCOA)+ #include <sys/param.h> // For MAXPATHLEN // Needed for _NSGetProgname@@ -174,7 +176,7 @@ // Create key code translation tables //-static void createKeyTables(void)+static void createKeyTablesCocoa(void) { memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes)); memset(_glfw.ns.scancodes, -1, sizeof(_glfw.ns.scancodes));@@ -492,78 +494,78 @@ { const _GLFWplatform cocoa = {- GLFW_PLATFORM_COCOA,- _glfwInitCocoa,- _glfwTerminateCocoa,- _glfwGetCursorPosCocoa,- _glfwSetCursorPosCocoa,- _glfwSetCursorModeCocoa,- _glfwSetRawMouseMotionCocoa,- _glfwRawMouseMotionSupportedCocoa,- _glfwCreateCursorCocoa,- _glfwCreateStandardCursorCocoa,- _glfwDestroyCursorCocoa,- _glfwSetCursorCocoa,- _glfwGetScancodeNameCocoa,- _glfwGetKeyScancodeCocoa,- _glfwSetClipboardStringCocoa,- _glfwGetClipboardStringCocoa,- _glfwInitJoysticksCocoa,- _glfwTerminateJoysticksCocoa,- _glfwPollJoystickCocoa,- _glfwGetMappingNameCocoa,- _glfwUpdateGamepadGUIDCocoa,- _glfwFreeMonitorCocoa,- _glfwGetMonitorPosCocoa,- _glfwGetMonitorContentScaleCocoa,- _glfwGetMonitorWorkareaCocoa,- _glfwGetVideoModesCocoa,- _glfwGetVideoModeCocoa,- _glfwGetGammaRampCocoa,- _glfwSetGammaRampCocoa,- _glfwCreateWindowCocoa,- _glfwDestroyWindowCocoa,- _glfwSetWindowTitleCocoa,- _glfwSetWindowIconCocoa,- _glfwGetWindowPosCocoa,- _glfwSetWindowPosCocoa,- _glfwGetWindowSizeCocoa,- _glfwSetWindowSizeCocoa,- _glfwSetWindowSizeLimitsCocoa,- _glfwSetWindowAspectRatioCocoa,- _glfwGetFramebufferSizeCocoa,- _glfwGetWindowFrameSizeCocoa,- _glfwGetWindowContentScaleCocoa,- _glfwIconifyWindowCocoa,- _glfwRestoreWindowCocoa,- _glfwMaximizeWindowCocoa,- _glfwShowWindowCocoa,- _glfwHideWindowCocoa,- _glfwRequestWindowAttentionCocoa,- _glfwFocusWindowCocoa,- _glfwSetWindowMonitorCocoa,- _glfwWindowFocusedCocoa,- _glfwWindowIconifiedCocoa,- _glfwWindowVisibleCocoa,- _glfwWindowMaximizedCocoa,- _glfwWindowHoveredCocoa,- _glfwFramebufferTransparentCocoa,- _glfwGetWindowOpacityCocoa,- _glfwSetWindowResizableCocoa,- _glfwSetWindowDecoratedCocoa,- _glfwSetWindowFloatingCocoa,- _glfwSetWindowOpacityCocoa,- _glfwSetWindowMousePassthroughCocoa,- _glfwPollEventsCocoa,- _glfwWaitEventsCocoa,- _glfwWaitEventsTimeoutCocoa,- _glfwPostEmptyEventCocoa,- _glfwGetEGLPlatformCocoa,- _glfwGetEGLNativeDisplayCocoa,- _glfwGetEGLNativeWindowCocoa,- _glfwGetRequiredInstanceExtensionsCocoa,- _glfwGetPhysicalDevicePresentationSupportCocoa,- _glfwCreateWindowSurfaceCocoa,+ .platformID = GLFW_PLATFORM_COCOA,+ .init = _glfwInitCocoa,+ .terminate = _glfwTerminateCocoa,+ .getCursorPos = _glfwGetCursorPosCocoa,+ .setCursorPos = _glfwSetCursorPosCocoa,+ .setCursorMode = _glfwSetCursorModeCocoa,+ .setRawMouseMotion = _glfwSetRawMouseMotionCocoa,+ .rawMouseMotionSupported = _glfwRawMouseMotionSupportedCocoa,+ .createCursor = _glfwCreateCursorCocoa,+ .createStandardCursor = _glfwCreateStandardCursorCocoa,+ .destroyCursor = _glfwDestroyCursorCocoa,+ .setCursor = _glfwSetCursorCocoa,+ .getScancodeName = _glfwGetScancodeNameCocoa,+ .getKeyScancode = _glfwGetKeyScancodeCocoa,+ .setClipboardString = _glfwSetClipboardStringCocoa,+ .getClipboardString = _glfwGetClipboardStringCocoa,+ .initJoysticks = _glfwInitJoysticksCocoa,+ .terminateJoysticks = _glfwTerminateJoysticksCocoa,+ .pollJoystick = _glfwPollJoystickCocoa,+ .getMappingName = _glfwGetMappingNameCocoa,+ .updateGamepadGUID = _glfwUpdateGamepadGUIDCocoa,+ .freeMonitor = _glfwFreeMonitorCocoa,+ .getMonitorPos = _glfwGetMonitorPosCocoa,+ .getMonitorContentScale = _glfwGetMonitorContentScaleCocoa,+ .getMonitorWorkarea = _glfwGetMonitorWorkareaCocoa,+ .getVideoModes = _glfwGetVideoModesCocoa,+ .getVideoMode = _glfwGetVideoModeCocoa,+ .getGammaRamp = _glfwGetGammaRampCocoa,+ .setGammaRamp = _glfwSetGammaRampCocoa,+ .createWindow = _glfwCreateWindowCocoa,+ .destroyWindow = _glfwDestroyWindowCocoa,+ .setWindowTitle = _glfwSetWindowTitleCocoa,+ .setWindowIcon = _glfwSetWindowIconCocoa,+ .getWindowPos = _glfwGetWindowPosCocoa,+ .setWindowPos = _glfwSetWindowPosCocoa,+ .getWindowSize = _glfwGetWindowSizeCocoa,+ .setWindowSize = _glfwSetWindowSizeCocoa,+ .setWindowSizeLimits = _glfwSetWindowSizeLimitsCocoa,+ .setWindowAspectRatio = _glfwSetWindowAspectRatioCocoa,+ .getFramebufferSize = _glfwGetFramebufferSizeCocoa,+ .getWindowFrameSize = _glfwGetWindowFrameSizeCocoa,+ .getWindowContentScale = _glfwGetWindowContentScaleCocoa,+ .iconifyWindow = _glfwIconifyWindowCocoa,+ .restoreWindow = _glfwRestoreWindowCocoa,+ .maximizeWindow = _glfwMaximizeWindowCocoa,+ .showWindow = _glfwShowWindowCocoa,+ .hideWindow = _glfwHideWindowCocoa,+ .requestWindowAttention = _glfwRequestWindowAttentionCocoa,+ .focusWindow = _glfwFocusWindowCocoa,+ .setWindowMonitor = _glfwSetWindowMonitorCocoa,+ .windowFocused = _glfwWindowFocusedCocoa,+ .windowIconified = _glfwWindowIconifiedCocoa,+ .windowVisible = _glfwWindowVisibleCocoa,+ .windowMaximized = _glfwWindowMaximizedCocoa,+ .windowHovered = _glfwWindowHoveredCocoa,+ .framebufferTransparent = _glfwFramebufferTransparentCocoa,+ .getWindowOpacity = _glfwGetWindowOpacityCocoa,+ .setWindowResizable = _glfwSetWindowResizableCocoa,+ .setWindowDecorated = _glfwSetWindowDecoratedCocoa,+ .setWindowFloating = _glfwSetWindowFloatingCocoa,+ .setWindowOpacity = _glfwSetWindowOpacityCocoa,+ .setWindowMousePassthrough = _glfwSetWindowMousePassthroughCocoa,+ .pollEvents = _glfwPollEventsCocoa,+ .waitEvents = _glfwWaitEventsCocoa,+ .waitEventsTimeout = _glfwWaitEventsTimeoutCocoa,+ .postEmptyEvent = _glfwPostEmptyEventCocoa,+ .getEGLPlatform = _glfwGetEGLPlatformCocoa,+ .getEGLNativeDisplay = _glfwGetEGLNativeDisplayCocoa,+ .getEGLNativeWindow = _glfwGetEGLNativeWindowCocoa,+ .getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsCocoa,+ .getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportCocoa,+ .createWindowSurface = _glfwCreateWindowSurfaceCocoa }; *platform = cocoa;@@ -617,7 +619,7 @@ name:NSTextInputContextKeyboardSelectionDidChangeNotification object:nil]; - createKeyTables();+ createKeyTablesCocoa(); _glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); if (!_glfw.ns.eventSource)@@ -689,4 +691,6 @@ } // autoreleasepool }++#endif // _GLFW_COCOA
raylib/src/external/glfw/src/cocoa_joystick.h view
@@ -31,8 +31,6 @@ #define GLFW_COCOA_JOYSTICK_STATE _GLFWjoystickNS ns; #define GLFW_COCOA_LIBRARY_JOYSTICK_STATE -#define GLFW_BUILD_COCOA_MAPPINGS- // Cocoa-specific per-joystick data // typedef struct _GLFWjoystickNS
raylib/src/external/glfw/src/cocoa_joystick.m view
@@ -24,11 +24,11 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" +#if defined(_GLFW_COCOA)+ #include <unistd.h> #include <ctype.h> #include <string.h>@@ -134,6 +134,14 @@ return; } + CFArrayRef elements =+ IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);++ // It is reportedly possible for this to fail on macOS 13 Ventura+ // if the application does not have input monitoring permissions+ if (!elements)+ return;+ axes = CFArrayCreateMutable(NULL, 0, NULL); buttons = CFArrayCreateMutable(NULL, 0, NULL); hats = CFArrayCreateMutable(NULL, 0, NULL);@@ -177,9 +185,6 @@ name[8], name[9], name[10]); } - CFArrayRef elements =- IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);- for (CFIndex i = 0; i < CFArrayGetCount(elements); i++) { IOHIDElementRef native = (IOHIDElementRef)@@ -475,4 +480,6 @@ original, original + 16); } }++#endif // _GLFW_COCOA
raylib/src/external/glfw/src/cocoa_monitor.m view
@@ -1,8 +1,9 @@ //========================================================================-// GLFW 3.4 macOS - www.glfw.org+// GLFW 3.4 macOS (modified for raylib) - www.glfw.org; www.raylib.com //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>+// Copyright (c) 2024 M374LX <wilsalx@gmail.com> // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages@@ -24,11 +25,11 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" +#if defined(_GLFW_COCOA)+ #include <stdlib.h> #include <limits.h> #include <math.h>@@ -549,13 +550,20 @@ } // autoreleasepool } -void _glfwGetVideoModeCocoa(_GLFWmonitor* monitor, GLFWvidmode *mode)+GLFWbool _glfwGetVideoModeCocoa(_GLFWmonitor* monitor, GLFWvidmode *mode) { @autoreleasepool { CGDisplayModeRef native = CGDisplayCopyDisplayMode(monitor->ns.displayID);+ if (!native)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to query display mode");+ return GLFW_FALSE;+ }+ *mode = vidmodeFromCGDisplayMode(native, monitor->ns.fallbackRefreshRate); CGDisplayModeRelease(native);+ return GLFW_TRUE; } // autoreleasepool }@@ -622,6 +630,15 @@ { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay);++ if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)+ {+ _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Cocoa: Platform not initialized");+ return kCGNullDirectDisplay;+ }+ return monitor->ns.displayID; }++#endif // _GLFW_COCOA
raylib/src/external/glfw/src/cocoa_platform.h view
@@ -145,7 +145,7 @@ GLFWbool maximized; GLFWbool occluded;- GLFWbool retina;+ GLFWbool scaleFramebuffer; // Cached window properties to filter out duplicate events int width, height;@@ -281,7 +281,7 @@ void _glfwGetMonitorContentScaleCocoa(_GLFWmonitor* monitor, float* xscale, float* yscale); void _glfwGetMonitorWorkareaCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height); GLFWvidmode* _glfwGetVideoModesCocoa(_GLFWmonitor* monitor, int* count);-void _glfwGetVideoModeCocoa(_GLFWmonitor* monitor, GLFWvidmode* mode);+GLFWbool _glfwGetVideoModeCocoa(_GLFWmonitor* monitor, GLFWvidmode* mode); GLFWbool _glfwGetGammaRampCocoa(_GLFWmonitor* monitor, GLFWgammaramp* ramp); void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
raylib/src/external/glfw/src/cocoa_time.c view
@@ -23,11 +23,11 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_COCOA_TIMER)+ #include <mach/mach_time.h> @@ -52,4 +52,6 @@ { return _glfw.timer.ns.frequency; }++#endif // GLFW_BUILD_COCOA_TIMER
raylib/src/external/glfw/src/cocoa_window.m view
@@ -23,11 +23,11 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" +#if defined(_GLFW_COCOA)+ #include <float.h> #include <string.h> @@ -111,7 +111,7 @@ // Make the specified window and its video mode active on its monitor //-static void acquireMonitor(_GLFWwindow* window)+static void acquireMonitorCocoa(_GLFWwindow* window) { _glfwSetVideoModeCocoa(window->monitor, &window->videoMode); const CGRect bounds = CGDisplayBounds(window->monitor->ns.displayID);@@ -127,7 +127,7 @@ // Remove the window and restore the original video mode //-static void releaseMonitor(_GLFWwindow* window)+static void releaseMonitorCocoa(_GLFWwindow* window) { if (window->monitor->window != window) return;@@ -158,7 +158,7 @@ // Translates a macOS keycode to a GLFW keycode //-static int translateKey(unsigned int key)+static int translateKeyCocoa(unsigned int key) { if (key >= sizeof(_glfw.ns.keycodes) / sizeof(_glfw.ns.keycodes[0])) return GLFW_KEY_UNKNOWN;@@ -277,7 +277,7 @@ - (void)windowDidMiniaturize:(NSNotification *)notification { if (window->monitor)- releaseMonitor(window);+ releaseMonitorCocoa(window); _glfwInputWindowIconify(window, GLFW_TRUE); }@@ -285,7 +285,7 @@ - (void)windowDidDeminiaturize:(NSNotification *)notification { if (window->monitor)- acquireMonitor(window);+ acquireMonitorCocoa(window); _glfwInputWindowIconify(window, GLFW_FALSE); }@@ -309,10 +309,15 @@ - (void)windowDidChangeOcclusionState:(NSNotification* )notification {- if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible)- window->ns.occluded = GLFW_FALSE;- else- window->ns.occluded = GLFW_TRUE;+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090+ if ([window->ns.object respondsToSelector:@selector(occlusionState)])+ {+ if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible)+ window->ns.occluded = GLFW_FALSE;+ else+ window->ns.occluded = GLFW_TRUE;+ }+#endif } @end@@ -508,7 +513,7 @@ if (xscale != window->ns.xscale || yscale != window->ns.yscale) {- if (window->ns.retina && window->ns.layer)+ if (window->ns.scaleFramebuffer && window->ns.layer) [window->ns.layer setContentsScale:[window->ns.object backingScaleFactor]]; window->ns.xscale = xscale;@@ -556,7 +561,7 @@ - (void)keyDown:(NSEvent *)event {- const int key = translateKey([event keyCode]);+ const int key = translateKeyCocoa([event keyCode]); const int mods = translateFlags([event modifierFlags]); _glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods);@@ -569,7 +574,7 @@ int action; const unsigned int modifierFlags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;- const int key = translateKey([event keyCode]);+ const int key = translateKeyCocoa([event keyCode]); const int mods = translateFlags(modifierFlags); const NSUInteger keyFlag = translateKeyToModifierFlag(key); @@ -588,7 +593,7 @@ - (void)keyUp:(NSEvent *)event {- const int key = translateKey([event keyCode]);+ const int key = translateKeyCocoa([event keyCode]); const int mods = translateFlags([event modifierFlags]); _glfwInputKey(window, key, [event keyCode], GLFW_RELEASE, mods); }@@ -867,7 +872,7 @@ [window->ns.object setFrameAutosaveName:@(wndconfig->ns.frameName)]; window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window];- window->ns.retina = wndconfig->ns.retina;+ window->ns.scaleFramebuffer = wndconfig->scaleFramebuffer; if (fbconfig->transparent) {@@ -961,7 +966,7 @@ { _glfwShowWindowCocoa(window); _glfwFocusWindowCocoa(window);- acquireMonitor(window);+ acquireMonitorCocoa(window); if (wndconfig->centerCursor) _glfwCenterCursorInContentArea(window);@@ -991,7 +996,7 @@ [window->ns.object orderOut:nil]; if (window->monitor)- releaseMonitor(window);+ releaseMonitorCocoa(window); if (window->context.destroy) window->context.destroy(window);@@ -1078,7 +1083,7 @@ if (window->monitor) { if (window->monitor->window == window)- acquireMonitor(window);+ acquireMonitorCocoa(window); } else {@@ -1247,7 +1252,7 @@ if (monitor) { if (monitor->window == window)- acquireMonitor(window);+ acquireMonitorCocoa(window); } else {@@ -1265,7 +1270,7 @@ } if (window->monitor)- releaseMonitor(window);+ releaseMonitorCocoa(window); _glfwInputWindowMonitor(window, monitor); @@ -1277,7 +1282,7 @@ if (window->monitor) {- styleMask &= ~(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable);+ styleMask &= ~(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable); styleMask |= NSWindowStyleMaskBorderless; } else@@ -1303,7 +1308,7 @@ [window->ns.object setLevel:NSMainMenuWindowLevel + 1]; [window->ns.object setHasShadow:NO]; - acquireMonitor(window);+ acquireMonitorCocoa(window); } else {@@ -1652,14 +1657,15 @@ { @autoreleasepool { - if (scancode < 0 || scancode > 0xff ||- _glfw.ns.keycodes[scancode] == GLFW_KEY_UNKNOWN)+ if (scancode < 0 || scancode > 0xff) { _glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode); return NULL; } const int key = _glfw.ns.keycodes[scancode];+ if (key == GLFW_KEY_UNKNOWN)+ return NULL; UInt32 deadKeyState = 0; UniChar characters[4];@@ -1963,7 +1969,7 @@ return VK_ERROR_EXTENSION_NOT_PRESENT; } - if (window->ns.retina)+ if (window->ns.scaleFramebuffer) [window->ns.layer setContentsScale:[window->ns.object backingScaleFactor]]; [window->ns.view setLayer:window->ns.layer];@@ -2041,9 +2047,26 @@ { _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Cocoa: Platform not initialized");- return NULL;+ return nil; } return window->ns.object; }++GLFWAPI id glfwGetCocoaView(GLFWwindow* handle)+{+ _GLFWwindow* window = (_GLFWwindow*) handle;+ _GLFW_REQUIRE_INIT_OR_RETURN(nil);++ if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)+ {+ _glfwInputError(GLFW_PLATFORM_UNAVAILABLE,+ "Cocoa: Platform not initialized");+ return nil;+ }++ return window->ns.view;+}++#endif // _GLFW_COCOA
raylib/src/external/glfw/src/context.c view
@@ -24,8 +24,6 @@ // distribution. // //========================================================================-// Please use C89 style variable declarations in this file because VS 2010-//======================================================================== #include "internal.h" @@ -363,6 +361,8 @@ previous = _glfwPlatformGetTls(&_glfw.contextSlot); glfwMakeContextCurrent((GLFWwindow*) window);+ if (_glfwPlatformGetTls(&_glfw.contextSlot) != window)+ return GLFW_FALSE; window->context.GetIntegerv = (PFNGLGETINTEGERVPROC) window->context.getProcAddress("glGetIntegerv");
raylib/src/external/glfw/src/egl_context.c view
@@ -24,8 +24,6 @@ // distribution. // //========================================================================-// Please use C89 style variable declarations in this file because VS 2010-//======================================================================== #include "internal.h" @@ -88,14 +86,31 @@ // Return the EGLConfig most closely matching the specified hints // static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,- const _GLFWfbconfig* desired,+ const _GLFWfbconfig* fbconfig, EGLConfig* result) { EGLConfig* nativeConfigs; _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest;- int i, nativeCount, usableCount;+ int i, nativeCount, usableCount, apiBit;+ GLFWbool wrongApiAvailable = GLFW_FALSE; + if (ctxconfig->client == GLFW_OPENGL_ES_API)+ {+ if (ctxconfig->major == 1)+ apiBit = EGL_OPENGL_ES_BIT;+ else+ apiBit = EGL_OPENGL_ES2_BIT;+ }+ else+ apiBit = EGL_OPENGL_BIT;++ if (fbconfig->stereo)+ {+ _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Stereo rendering not supported");+ return GLFW_FALSE;+ }+ eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount); if (!nativeCount) {@@ -132,7 +147,7 @@ if (!vi.visualid) continue; - if (desired->transparent)+ if (fbconfig->transparent) { int count; XVisualInfo* vis =@@ -146,23 +161,10 @@ } #endif // _GLFW_X11 - if (ctxconfig->client == GLFW_OPENGL_ES_API)- {- if (ctxconfig->major == 1)- {- if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT))- continue;- }- else- {- if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT))- continue;- }- }- else if (ctxconfig->client == GLFW_OPENGL_API)+ if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & apiBit)) {- if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT))- continue;+ wrongApiAvailable = GLFW_TRUE;+ continue; } u->redBits = getEGLConfigAttrib(n, EGL_RED_SIZE);@@ -182,22 +184,51 @@ // with an alpha channel to ensure the buffer is opaque if (!_glfw.egl.EXT_present_opaque) {- if (!desired->transparent && u->alphaBits > 0)+ if (!fbconfig->transparent && u->alphaBits > 0) continue; } } #endif // _GLFW_WAYLAND u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);- u->doublebuffer = desired->doublebuffer;+ u->doublebuffer = fbconfig->doublebuffer; u->handle = (uintptr_t) n; usableCount++; } - closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);+ closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount); if (closest) *result = (EGLConfig) closest->handle;+ else+ {+ if (wrongApiAvailable)+ {+ if (ctxconfig->client == GLFW_OPENGL_ES_API)+ {+ if (ctxconfig->major == 1)+ {+ _glfwInputError(GLFW_API_UNAVAILABLE,+ "EGL: Failed to find support for OpenGL ES 1.x");+ }+ else+ {+ _glfwInputError(GLFW_API_UNAVAILABLE,+ "EGL: Failed to find support for OpenGL ES 2 or later");+ }+ }+ else+ {+ _glfwInputError(GLFW_API_UNAVAILABLE,+ "EGL: Failed to find support for OpenGL");+ }+ }+ else+ {+ _glfwInputError(GLFW_FORMAT_UNAVAILABLE,+ "EGL: Failed to find a suitable EGLConfig");+ }+ } _glfw_free(nativeConfigs); _glfw_free(usableConfigs);@@ -278,6 +309,7 @@ static GLFWglproc getProcAddressEGL(const char* procname) { _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);+ assert(window != NULL); if (window->context.egl.client) {@@ -550,11 +582,7 @@ share = ctxconfig->share->context.egl.handle; if (!chooseEGLConfig(ctxconfig, fbconfig, &config))- {- _glfwInputError(GLFW_FORMAT_UNAVAILABLE,- "EGL: Failed to find a suitable EGLConfig"); return GLFW_FALSE;- } if (ctxconfig->client == GLFW_OPENGL_ES_API) {@@ -611,18 +639,18 @@ flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; } - if (ctxconfig->noerror)- {- if (_glfw.egl.KHR_create_context_no_error)- SET_ATTRIB(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);- }- if (ctxconfig->major != 1 || ctxconfig->minor != 0) { SET_ATTRIB(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major); SET_ATTRIB(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor); } + if (ctxconfig->noerror)+ {+ if (_glfw.egl.KHR_create_context_no_error)+ SET_ATTRIB(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);+ }+ if (mask) SET_ATTRIB(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask); @@ -674,8 +702,11 @@ if (!fbconfig->doublebuffer) SET_ATTRIB(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER); - if (_glfw.egl.EXT_present_opaque)- SET_ATTRIB(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);+ if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)+ {+ if (_glfw.egl.EXT_present_opaque)+ SET_ATTRIB(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);+ } SET_ATTRIB(EGL_NONE, EGL_NONE); @@ -815,11 +846,7 @@ const long vimask = VisualScreenMask | VisualIDMask; if (!chooseEGLConfig(ctxconfig, fbconfig, &native))- {- _glfwInputError(GLFW_FORMAT_UNAVAILABLE,- "EGL: Failed to find a suitable EGLConfig"); return GLFW_FALSE;- } eglGetConfigAttrib(_glfw.egl.display, native, EGL_NATIVE_VISUAL_ID, &visualID);
raylib/src/external/glfw/src/glx_context.c view
@@ -24,11 +24,11 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" +#if defined(_GLFW_X11)+ #include <string.h> #include <stdlib.h> #include <assert.h>@@ -190,6 +190,7 @@ static void swapIntervalGLX(int interval) { _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);+ assert(window != NULL); if (_glfw.glx.EXT_swap_control) {@@ -713,4 +714,6 @@ return window->context.glx.window; }++#endif // _GLFW_X11
raylib/src/external/glfw/src/init.c view
@@ -24,8 +24,6 @@ // distribution. // //========================================================================-// Please use C89 style variable declarations in this file because VS 2010-//======================================================================== #include "internal.h" @@ -51,17 +49,23 @@ static GLFWallocator _glfwInitAllocator; static _GLFWinitconfig _glfwInitHints = {- GLFW_TRUE, // hat buttons- GLFW_ANGLE_PLATFORM_TYPE_NONE, // ANGLE backend- GLFW_ANY_PLATFORM, // preferred platform- NULL, // vkGetInstanceProcAddr function+ .hatButtons = GLFW_TRUE,+ .angleType = GLFW_ANGLE_PLATFORM_TYPE_NONE,+ .platformID = GLFW_ANY_PLATFORM,+ .vulkanLoader = NULL,+ .ns = {- GLFW_TRUE, // macOS menu bar- GLFW_TRUE // macOS bundle chdir+ .menubar = GLFW_TRUE,+ .chdir = GLFW_TRUE },+ .x11 = {- GLFW_TRUE, // X11 XCB Vulkan surface+ .xcbVulkanSurface = GLFW_TRUE, },+ .wl =+ {+ .libdecorMode = GLFW_WAYLAND_PREFER_LIBDECOR+ }, }; // The allocation function used when no custom allocator is set@@ -242,30 +246,6 @@ return a > b ? a : b; } -float _glfw_fminf(float a, float b)-{- if (a != a)- return b;- else if (b != b)- return a;- else if (a < b)- return a;- else- return b;-}--float _glfw_fmaxf(float a, float b)-{- if (a != a)- return b;- else if (b != b)- return a;- else if (a > b)- return a;- else- return b;-}- void* _glfw_calloc(size_t count, size_t size) { if (count && size)@@ -478,6 +458,9 @@ return; case GLFW_X11_XCB_VULKAN_SURFACE: _glfwInitHints.x11.xcbVulkanSurface = value;+ return;+ case GLFW_WAYLAND_LIBDECOR:+ _glfwInitHints.wl.libdecorMode = value; return; }
raylib/src/external/glfw/src/input.c view
@@ -24,8 +24,6 @@ // distribution. // //========================================================================-// Please use C89 style variable declarations in this file because VS 2010-//======================================================================== #include "internal.h" #include "mappings.h"@@ -462,10 +460,11 @@ assert(hat >= 0); assert(hat < js->hatCount); - // Valid hat values only use the least significant nibble and have at most two bits- // set, which can be considered adjacent plus an arbitrary rotation within the nibble+ // Valid hat values only use the least significant nibble assert((value & 0xf0) == 0);- assert((value & ((value << 2) | (value >> 2))) == 0);+ // Valid hat values do not have both bits of an axis set+ assert((value & GLFW_HAT_LEFT) == 0 || (value & GLFW_HAT_RIGHT) == 0);+ assert((value & GLFW_HAT_UP) == 0 || (value & GLFW_HAT_DOWN) == 0); base = js->buttonCount + hat * 4; @@ -701,6 +700,12 @@ if (key != GLFW_KEY_UNKNOWN) {+ if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)+ {+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);+ return NULL;+ }+ if (key != GLFW_KEY_KP_EQUAL && (key < GLFW_KEY_KP_0 || key > GLFW_KEY_KP_ADD) && (key < GLFW_KEY_APOSTROPHE || key > GLFW_KEY_WORLD_2))@@ -716,12 +721,12 @@ GLFWAPI int glfwGetKeyScancode(int key) {- _GLFW_REQUIRE_INIT_OR_RETURN(-1);+ _GLFW_REQUIRE_INIT_OR_RETURN(0); if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST) { _glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);- return GLFW_RELEASE;+ return -1; } return _glfw.platform.getKeyScancode(key);@@ -1433,7 +1438,7 @@ if (e->type == _GLFW_JOYSTICK_AXIS) { const float value = js->axes[e->index] * e->axisScale + e->axisOffset;- state->axes[i] = _glfw_fminf(_glfw_fmaxf(value, -1.f), 1.f);+ state->axes[i] = fminf(fmaxf(value, -1.f), 1.f); } else if (e->type == _GLFW_JOYSTICK_HATBIT) {
raylib/src/external/glfw/src/internal.h view
@@ -108,12 +108,6 @@ typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*); typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint); -#if defined(_GLFW_WIN32)- #define EGLAPIENTRY __stdcall-#else- #define EGLAPIENTRY-#endif- #define EGL_SUCCESS 0x3000 #define EGL_NOT_INITIALIZED 0x3001 #define EGL_BAD_ACCESS 0x3002@@ -200,22 +194,22 @@ typedef void* EGLNativeWindowType; // EGL function pointer typedefs-typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);-typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigs)(EGLDisplay,EGLConfig*,EGLint,EGLint*);-typedef EGLDisplay (EGLAPIENTRY * PFN_eglGetDisplay)(EGLNativeDisplayType);-typedef EGLint (EGLAPIENTRY * PFN_eglGetError)(void);-typedef EGLBoolean (EGLAPIENTRY * PFN_eglInitialize)(EGLDisplay,EGLint*,EGLint*);-typedef EGLBoolean (EGLAPIENTRY * PFN_eglTerminate)(EGLDisplay);-typedef EGLBoolean (EGLAPIENTRY * PFN_eglBindAPI)(EGLenum);-typedef EGLContext (EGLAPIENTRY * PFN_eglCreateContext)(EGLDisplay,EGLConfig,EGLContext,const EGLint*);-typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface);-typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext);-typedef EGLSurface (EGLAPIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*);-typedef EGLBoolean (EGLAPIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext);-typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface);-typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint);-typedef const char* (EGLAPIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint);-typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*);+typedef EGLBoolean (APIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);+typedef EGLBoolean (APIENTRY * PFN_eglGetConfigs)(EGLDisplay,EGLConfig*,EGLint,EGLint*);+typedef EGLDisplay (APIENTRY * PFN_eglGetDisplay)(EGLNativeDisplayType);+typedef EGLint (APIENTRY * PFN_eglGetError)(void);+typedef EGLBoolean (APIENTRY * PFN_eglInitialize)(EGLDisplay,EGLint*,EGLint*);+typedef EGLBoolean (APIENTRY * PFN_eglTerminate)(EGLDisplay);+typedef EGLBoolean (APIENTRY * PFN_eglBindAPI)(EGLenum);+typedef EGLContext (APIENTRY * PFN_eglCreateContext)(EGLDisplay,EGLConfig,EGLContext,const EGLint*);+typedef EGLBoolean (APIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface);+typedef EGLBoolean (APIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext);+typedef EGLSurface (APIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*);+typedef EGLBoolean (APIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext);+typedef EGLBoolean (APIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface);+typedef EGLBoolean (APIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint);+typedef const char* (APIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint);+typedef GLFWglproc (APIENTRY * PFN_eglGetProcAddress)(const char*); #define eglGetConfigAttrib _glfw.egl.GetConfigAttrib #define eglGetConfigs _glfw.egl.GetConfigs #define eglGetDisplay _glfw.egl.GetDisplay@@ -233,8 +227,8 @@ #define eglQueryString _glfw.egl.QueryString #define eglGetProcAddress _glfw.egl.GetProcAddress -typedef EGLDisplay (EGLAPIENTRY * PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum,void*,const EGLint*);-typedef EGLSurface (EGLAPIENTRY * PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay,EGLConfig,void*,const EGLint*);+typedef EGLDisplay (APIENTRY * PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum,void*,const EGLint*);+typedef EGLSurface (APIENTRY * PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay,EGLConfig,void*,const EGLint*); #define eglGetPlatformDisplayEXT _glfw.egl.GetPlatformDisplayEXT #define eglCreatePlatformWindowSurfaceEXT _glfw.egl.CreatePlatformWindowSurfaceEXT @@ -330,12 +324,8 @@ #include "platform.h" -// Constructs a version number string from the public header macros-#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r-#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r)-#define _GLFW_VERSION_NUMBER _GLFW_MAKE_VERSION(GLFW_VERSION_MAJOR, \- GLFW_VERSION_MINOR, \- GLFW_VERSION_REVISION)+#define GLFW_NATIVE_INCLUDE_NONE+#include "../include/GLFW/glfw3native.h" // Checks for whether the library has been initialized #define _GLFW_REQUIRE_INIT() \@@ -386,6 +376,9 @@ struct { GLFWbool xcbVulkanSurface; } x11;+ struct {+ int libdecorMode;+ } wl; }; // Window configuration@@ -412,8 +405,8 @@ GLFWbool focusOnShow; GLFWbool mousePassthrough; GLFWbool scaleToMonitor;+ GLFWbool scaleFramebuffer; struct {- GLFWbool retina; char frameName[256]; } ns; struct {@@ -422,6 +415,7 @@ } x11; struct { GLFWbool keymenu;+ GLFWbool showDefault; } win32; struct { char appId[256];@@ -541,6 +535,7 @@ GLFWvidmode videoMode; _GLFWmonitor* monitor; _GLFWcursor* cursor;+ char* title; int minwidth, minheight; int maxwidth, maxheight;@@ -705,7 +700,7 @@ void (*getMonitorContentScale)(_GLFWmonitor*,float*,float*); void (*getMonitorWorkarea)(_GLFWmonitor*,int*,int*,int*,int*); GLFWvidmode* (*getVideoModes)(_GLFWmonitor*,int*);- void (*getVideoMode)(_GLFWmonitor*,GLFWvidmode*);+ GLFWbool (*getVideoMode)(_GLFWmonitor*,GLFWvidmode*); GLFWbool (*getGammaRamp)(_GLFWmonitor*,GLFWgammaramp*); void (*setGammaRamp)(_GLFWmonitor*,const GLFWgammaramp*); // window@@ -1007,8 +1002,6 @@ char* _glfw_strdup(const char* source); int _glfw_min(int a, int b); int _glfw_max(int a, int b);-float _glfw_fminf(float a, float b);-float _glfw_fmaxf(float a, float b); void* _glfw_calloc(size_t count, size_t size); void* _glfw_realloc(void* pointer, size_t size);
raylib/src/external/glfw/src/linux_joystick.c view
@@ -24,11 +24,11 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_LINUX_JOYSTICK)+ #include <sys/types.h> #include <sys/stat.h> #include <sys/inotify.h>@@ -135,7 +135,7 @@ } _GLFWjoystickLinux linjs = {0};- linjs.fd = open(path, O_RDONLY | O_NONBLOCK);+ linjs.fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC); if (linjs.fd == -1) return GLFW_FALSE; @@ -324,7 +324,8 @@ // Continue without device connection notifications if inotify fails - if (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) != 0)+ _glfw.linjs.regexCompiled = (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) == 0);+ if (!_glfw.linjs.regexCompiled) { _glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex"); return GLFW_FALSE;@@ -376,8 +377,10 @@ inotify_rm_watch(_glfw.linjs.inotify, _glfw.linjs.watch); close(_glfw.linjs.inotify);- regfree(&_glfw.linjs.regex); }++ if (_glfw.linjs.regexCompiled)+ regfree(&_glfw.linjs.regex); } GLFWbool _glfwPollJoystickLinux(_GLFWjoystick* js, int mode)@@ -428,4 +431,6 @@ void _glfwUpdateGamepadGUIDLinux(char* guid) { }++#endif // GLFW_BUILD_LINUX_JOYSTICK
raylib/src/external/glfw/src/linux_joystick.h view
@@ -31,8 +31,6 @@ #define GLFW_LINUX_JOYSTICK_STATE _GLFWjoystickLinux linjs; #define GLFW_LINUX_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs; -#define GLFW_BUILD_LINUX_MAPPINGS- // Linux-specific joystick data // typedef struct _GLFWjoystickLinux@@ -52,6 +50,7 @@ int inotify; int watch; regex_t regex;+ GLFWbool regexCompiled; GLFWbool dropped; } _GLFWlibraryLinux;
raylib/src/external/glfw/src/mappings.h view
@@ -60,1507 +60,942 @@ const char* _glfwDefaultMappings[] = {-#if defined(GLFW_BUILD_WIN32_MAPPINGS)-"03000000300f00000a01000000000000,3 In 1 Conversion Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b8,x:b3,y:b0,platform:Windows,",-"03000000fa2d00000100000000000000,3dRudder Foot Motion Controller,leftx:a0,lefty:a1,rightx:a5,righty:a2,platform:Windows,",-"03000000d0160000040d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,",-"03000000d0160000050d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,",-"03000000d0160000060d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,",-"03000000d0160000070d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,",-"03000000d0160000600a000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,",-"03000000c82d00000031000000000000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c82d00000531000000000000,8BitDo Adapter 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c82d00000951000000000000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a2,rightx:a3,righty:a5,start:b11,platform:Windows,",-"03000000008000000210000000000000,8BitDo F30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",-"030000003512000011ab000000000000,8BitDo F30 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000c82d00001028000000000000,8BitDo F30 Arcade Joystick,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c82d000011ab000000000000,8BitDo F30 Arcade Joystick,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",-"03000000801000000900000000000000,8BitDo F30 Arcade Stick,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c82d00001038000000000000,8BitDo F30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000090000000000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00001251000000000000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00001151000000000000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000150000000000000,8BitDo M30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a5,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000151000000000000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a2,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c82d00000650000000000000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c82d00005106000000000000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,guide:b2,leftshoulder:b8,lefttrigger:b9,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c82d00000310000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c82d00000451000000000000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a2,rightx:a3,righty:a5,start:b11,platform:Windows,",-"03000000c82d00002028000000000000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00008010000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c82d0000e002000000000000,8BitDo N30,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b6,platform:Windows,",-"03000000c82d00000190000000000000,8BitDo N30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00001590000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00006528000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000290000000000000,8BitDo N64,+rightx:b9,+righty:b3,-rightx:b4,-righty:b8,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,platform:Windows,",-"03000000c82d00003038000000000000,8BitDo N64,+rightx:b9,+righty:b3,-rightx:b4,-righty:b8,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,platform:Windows,",-"030000003512000012ab000000000000,8BitDo NES30,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Windows,",-"03000000c82d000012ab000000000000,8BitDo NES30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",-"03000000022000000090000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",-"03000000203800000900000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00002038000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000751000000000000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c82d00000851000000000000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c82d00000360000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000361000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000660000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000131000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000231000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000331000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000431000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00002867000000000000,8BitDo S30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a2,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a5,start:b10,x:b3,y:b4,platform:Windows,",-"03000000c82d00000130000000000000,8BitDo SF30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000060000000000000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000061000000000000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,",-"03000000102800000900000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d000021ab000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00003028000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",-"030000003512000020ab000000000000,8BitDo SN30,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000030000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000351000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a2,rightshoulder:b7,rightx:a3,righty:a5,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00001290000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d000020ab000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00004028000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00006228000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000021000000000000,8BitDo SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000121000000000000,8BitDo SN30 Pro for Android,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c82d00000260000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00000261000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00001330000000000000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000a00500003232000000000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",-"03000000c82d00003032000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,",-"030000008f0e00001200000000000000,Acme GA02,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,",-"03000000c01100000355000000000000,Acrux,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000fa190000f0ff000000000000,Acteck AGJ 3200,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000d1180000402c000000000000,ADT1,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a3,rightx:a2,righty:a5,x:b3,y:b4,platform:Windows,",-"03000000341a00003608000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006f0e00000263000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006f0e00001101000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006f0e00001401000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006f0e00001402000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006f0e00001901000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006f0e00001a01000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006f0e00001301000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000006f0e00001302000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000006f0e00001304000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000006f0e00001413000000000000,Afterglow Xbox Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006f0e00003901000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000ab1200000103000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000ad1b000000f9000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000100000008200000000000000,Akishop Customs PS360,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"030000007c1800000006000000000000,Alienware Dual Compatible PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",-"03000000491900001904000000000000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows,",-"03000000710100001904000000000000,Amazon Luna Controller,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b8,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b4,rightstick:b7,rightx:a3,righty:a4,start:b6,x:b3,y:b2,platform:Windows,",-"03000000830500000160000000000000,Arcade,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b3,x:b4,y:b4,platform:Windows,",-"03000000120c0000100e000000000000,Armor 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000490b00004406000000000000,ASCII Seamic Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,",-"03000000869800002500000000000000,Astro C40 TR PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000a30c00002700000000000000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,",-"03000000a30c00002800000000000000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,",-"03000000050b00000579000000000000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000050b00000679000000000000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000e4150000103f000000000000,Batarang,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000d6200000e557000000000000,Batarang PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000c01100001352000000000000,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows,",-"030000006f0e00003201000000000000,Battlefield 4 PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000ad1b000001f9000000000000,BB 070,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000d62000002a79000000000000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000bc2000005250000000000000,Beitong G3,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:b9,rightx:a3,righty:a4,start:b15,x:b3,y:b4,platform:Windows,",-"030000000d0500000208000000000000,Belkin Nostromo N40,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,",-"03000000bc2000006012000000000000,Betop 2126F,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000bc2000000055000000000000,Betop BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000bc2000006312000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000bc2000006321000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000bc2000006412000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000c01100000555000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000c01100000655000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000790000000700000000000000,Betop Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,",-"03000000808300000300000000000000,Betop Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,",-"030000006f0e00006401000000000000,BF One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows,",-"03000000300f00000202000000000000,Bigben,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a5,righty:a2,start:b7,x:b2,y:b3,platform:Windows,",-"030000006b1400000209000000000000,Bigben,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006b1400000055000000000000,Bigben PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"030000006b1400000103000000000000,Bigben PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,",-"03000000120c0000200e000000000000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000210e000000000000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000f10e000000000000,Brook PS2 Adapter,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000310c000000000000,Brook Super Converter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,",-"03000000d81d00000b00000000000000,Buffalo BSGP1601 Series,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows,",-"030000005b1c00002400000000000000,Capcom Home Arcade Controller,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows,",-"030000005b1c00002500000000000000,Capcom Home Arcade Controller,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows,",-"030000006d04000042c2000000000000,ChillStream,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000e82000006058000000000000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000457500000401000000000000,Cobra,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000b0400003365000000000000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows,",-"030000004c050000c505000000000000,CronusMax Adapter,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000d814000007cd000000000000,Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000d8140000cefa000000000000,Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000260900008888000000000000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a4,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Windows,",-"030000003807000002cb000000000000,Cyborg,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000a306000022f6000000000000,Cyborg V.3 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",-"03000000f806000000a3000000000000,DA Leader,a:b7,b:b6,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b0,leftstick:b8,lefttrigger:b1,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:b3,rightx:a2,righty:a3,start:b12,x:b4,y:b5,platform:Windows,",-"030000001a1c00000001000000000000,Datel Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000451300000830000000000000,Defender Game Racer X7,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"03000000791d00000103000000000000,Dual Box Wii,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000c0160000e105000000000000,Dual Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",-"030000004f040000070f000000000000,Dual Power,a:b8,b:b9,back:b4,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,leftshoulder:b13,leftstick:b6,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b12,rightstick:b7,righttrigger:b15,start:b5,x:b10,y:b11,platform:Windows,",-"030000004f04000012b3000000000000,Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,",-"030000004f04000020b3000000000000,Dual Trigger,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,",-"03000000bd12000002e0000000000000,Dual Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,",-"03000000ff1100003133000000000000,DualForce,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b1,platform:Windows,",-"030000008f0e00000910000000000000,DualShock 2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,",-"03000000317300000100000000000000,DualShock 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",-"030000006f0e00003001000000000000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000fc0400000250000000000000,Easy Grip,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,",-"030000006e0500000a20000000000000,Elecom DUX60 MMO,a:b2,b:b3,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b14,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b15,righttrigger:b13,rightx:a3,righty:a4,start:b20,x:b0,y:b1,platform:Windows,",-"03000000b80500000410000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,",-"03000000b80500000610000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,",-"030000006e0500000520000000000000,Elecom P301U PlayStation Controller Adapter,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,",-"03000000411200004450000000000000,Elecom U1012,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,",-"030000006e0500000320000000000000,Elecom U3613M,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,",-"030000006e0500000e20000000000000,Elecom U3912T,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,",-"030000006e0500000f20000000000000,Elecom U4013S,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,",-"030000006e0500001320000000000000,Elecom U4113,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006e0500001020000000000000,Elecom U4113S,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows,",-"030000006e0500000720000000000000,Elecom W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,",-"030000007d0400000640000000000000,Eliminator AfterShock,a:b1,b:b2,back:b9,dpdown:+a3,dpleft:-a5,dpright:+a5,dpup:-a3,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a4,righty:a2,start:b8,x:b0,y:b3,platform:Windows,",-"03000000120c0000f61c000000000000,Elite,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000430b00000300000000000000,EMS Production PS2 Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",-"03000000242f000000b7000000000000,ESM 9110,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Windows,",-"03000000101c0000181c000000000000,Essential,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b4,leftx:a1,lefty:a0,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",-"030000008f0e00000f31000000000000,EXEQ,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,",-"03000000341a00000108000000000000,EXEQ RF Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"030000006f0e00008401000000000000,Faceoff Deluxe Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006f0e00008001000000000000,Faceoff Pro Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000021000000090000000000000,FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",-"0300000011040000c600000000000000,FC801,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,",-"03000000852100000201000000000000,FF GP1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000ad1b000028f0000000000000,Fightpad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000ad1b00002ef0000000000000,Fightpad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000ad1b000038f0000000000000,Fightpad TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,",-"03000000f806000001a3000000000000,Firestorm,a:b9,b:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b0,leftstick:b10,lefttrigger:b1,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b12,x:b8,y:b4,platform:Windows,",-"03000000b50700000399000000000000,Firestorm 2,a:b2,b:b4,back:b10,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,righttrigger:b9,start:b11,x:b3,y:b5,platform:Windows,",-"03000000b50700001302000000000000,Firestorm D3,a:b0,b:b2,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,x:b1,y:b3,platform:Windows,",-"03000000b40400001024000000000000,Flydigi Apex,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",-"03000000151900004000000000000000,Flydigi Vader 2,a:b11,b:b10,back:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,leftstick:b1,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b0,righttrigger:b4,rightx:a3,righty:a4,start:b2,x:b9,y:b8,platform:Windows,",-"03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,platform:Windows,",-"03000000b40400001224000000000000,Flydigi Vader 2 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,paddle3:b17,paddle4:b18,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,",-"030000008305000000a0000000000000,G08XU,a:b0,b:b1,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b5,x:b2,y:b3,platform:Windows,",-"0300000066f700000100000000000000,Game VIB Joystick,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows,",-"03000000260900002625000000000000,GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows,",-"03000000341a000005f7000000000000,GameCube Controller,a:b2,b:b3,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b1,y:b0,platform:Windows,",-"03000000430b00000500000000000000,GameCube Controller,a:b0,b:b2,dpdown:b10,dpleft:b8,dpright:b9,dpup:b11,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a3,rightx:a5,righty:a2,start:b7,x:b1,y:b3,platform:Windows,",-"03000000790000004718000000000000,GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,",-"03000000790000004618000000000000,GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,",-"030000008f0e00000d31000000000000,Gamepad 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000ac0500003d03000000000000,GameSir G3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000ac0500005b05000000000000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000ac0500002d02000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",-"03000000ac0500004d04000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"030000004c0e00001035000000000000,Gamester,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,",-"030000000d0f00001110000000000000,GameStick Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",-"0300000047530000616d000000000000,GameStop,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"03000000c01100000140000000000000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000b62500000100000000000000,Gametel GT004 01,a:b3,b:b0,dpdown:b10,dpleft:b9,dpright:b8,dpup:b11,leftshoulder:b4,rightshoulder:b5,start:b7,x:b1,y:b2,platform:Windows,",-"030000008f0e00001411000000000000,Gamo2 Divaller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000a857000000000000,Gator Claw,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000c9110000f055000000000000,GC100XF,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"030000008305000009a0000000000000,Genius,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"030000008305000031b0000000000000,Genius Maxfire Blaze 3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"03000000451300000010000000000000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"030000005c1a00003330000000000000,Genius MaxFire Grandias 12V,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,",-"03000000300f00000b01000000000000,GGE909 Recoil,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",-"03000000f0250000c283000000000000,Gioteck PlayStation Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000f025000021c1000000000000,Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000f025000031c1000000000000,Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000f0250000c383000000000000,Gioteck VX2 PlayStation Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000f0250000c483000000000000,Gioteck VX2 PlayStation Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"030000004f04000026b3000000000000,GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"0300000079000000d418000000000000,GPD Win,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000c6240000025b000000000000,GPX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000007d0400000840000000000000,Gravis Destroyer Tilt,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,x:b0,y:b3,platform:Windows,",-"030000007d0400000540000000000000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"03000000280400000140000000000000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a3,dpup:-a4,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"030000008f0e00000610000000000000,GreenAsia,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a5,righty:a2,start:b11,x:b3,y:b0,platform:Windows,",-"03000000ac0500006b05000000000000,GT2a,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",-"03000000341a00000302000000000000,Hama Scorpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00004900000000000000,Hatsune Miku Sho PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000001008000001e1000000000000,Havit HV G60,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows,",-"030000000d0f00000c00000000000000,HEXT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000d81400000862000000000000,HitBox Edition Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,",-"03000000632500002605000000000000,HJD X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"030000000d0f00000a00000000000000,Hori DOA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000000d0f00008500000000000000,Hori Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00002500000000000000,Hori Fighting Commander 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00002d00000000000000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00005f00000000000000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00005e00000000000000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00008400000000000000,Hori Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00005100000000000000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00008600000000000000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000000d0f0000ba00000000000000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000000d0f00008800000000000000,Hori Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,",-"030000000d0f00008700000000000000,Hori Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00001000000000000000,Hori Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00003200000000000000,Hori Fightstick 3W,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f0000c000000000000000,Hori Fightstick 4,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000000d0f00000d00000000000000,Hori Fightstick EX2,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,",-"030000000d0f00003701000000000000,Hori Fightstick Mini,a:b1,b:b0,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Windows,",-"030000000d0f00004000000000000000,Hori Fightstick Mini 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00002100000000000000,Hori Fightstick V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00002700000000000000,Hori Fightstick V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f0000a000000000000000,Hori Grip TAC4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b13,x:b0,y:b3,platform:Windows,",-"030000000d0f0000a500000000000000,Hori Miku Project Diva X HD PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f0000a600000000000000,Hori Miku Project Diva X HD PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00000101000000000000,Hori Mini Hatsune Miku FT,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00005400000000000000,Hori Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00000900000000000000,Hori Pad 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00004d00000000000000,Hori Pad A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00003801000000000000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Windows,",-"030000000d0f00009200000000000000,Hori Pokken Tournament DX Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00002301000000000000,Hori PS4 Controller Light,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",-"030000000d0f00001100000000000000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00002600000000000000,Hori Real Arcade Pro 3P,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00004b00000000000000,Hori Real Arcade Pro 3W,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00006a00000000000000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00006b00000000000000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00008a00000000000000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00008b00000000000000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00006f00000000000000,Hori Real Arcade Pro 4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00007000000000000000,Hori Real Arcade Pro 4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00003d00000000000000,Hori Real Arcade Pro N3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b10,leftstick:b4,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b6,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f0000ae00000000000000,Hori Real Arcade Pro N4,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000000d0f00008c00000000000000,Hori Real Arcade Pro P4,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000000d0f0000aa00000000000000,Hori Real Arcade Pro S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f0000d800000000000000,Hori Real Arcade Pro S,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Windows,",-"030000000d0f00002200000000000000,Hori Real Arcade Pro V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00005b00000000000000,Hori Real Arcade Pro V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00005c00000000000000,Hori Real Arcade Pro V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f0000af00000000000000,Hori Real Arcade Pro VHS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00001b00000000000000,Hori Real Arcade Pro VX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000ad1b000002f5000000000000,Hori Real Arcade Pro VX,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Windows,",-"030000000d0f00009c00000000000000,Hori TAC Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f0000c900000000000000,Hori Taiko Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f0000c100000000000000,Horipad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00006400000000000000,Horipad 3TP,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00001300000000000000,Horipad 3W,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00005500000000000000,Horipad 4 FPS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00006e00000000000000,Horipad 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00006600000000000000,Horipad 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00004200000000000000,Horipad A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000ad1b000001f5000000000000,Horipad EXT2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000000d0f0000ee00000000000000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f00006700000000000000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000000d0f0000dc00000000000000,Horipad Switch,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000008f0e00001330000000000000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Windows,",-"03000000790000004e95000000000000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Windows,",-"03000000d81d00000e00000000000000,iBuffalo AC02 Arcade Joystick,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,rightx:a2,righty:a5,start:b8,x:b4,y:b5,platform:Windows,",-"03000000d81d00000f00000000000000,iBuffalo BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000d81d00001000000000000000,iBuffalo BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"030000005c0a00000285000000000000,iDroidCon,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b6,platform:Windows,",-"03000000696400006964000000000000,iDroidCon Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000b50700001403000000000000,Impact Black,a:b2,b:b3,back:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",-"030000006f0e00002401000000000000,Injustice Fightstick PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"03000000830500005130000000000000,InterAct ActionPad,a:b0,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,",-"03000000ef0500000300000000000000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows,",-"03000000fd0500000230000000000000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a5,start:b11,x:b0,y:b1,platform:Windows,",-"03000000fd0500000030000000000000,Interact GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Windows,",-"03000000fd0500003902000000000000,InterAct Hammerhead,a:b3,b:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b2,lefttrigger:b8,rightshoulder:b7,rightstick:b5,righttrigger:b9,start:b10,x:b0,y:b1,platform:Windows,",-"03000000fd0500002a26000000000000,InterAct Hammerhead FX,a:b3,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b0,y:b1,platform:Windows,",-"03000000fd0500002f26000000000000,InterAct Hammerhead FX,a:b4,b:b5,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b1,y:b2,platform:Windows,",-"03000000fd0500005302000000000000,InterAct ProPad,a:b3,b:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Windows,",-"03000000ac0500002c02000000000000,Ipega Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000491900000204000000000000,Ipega PG9023,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000491900000304000000000000,Ipega PG9087,+righty:+a5,-righty:-a4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,start:b11,x:b3,y:b4,platform:Windows,",-"030000007e0500000620000000000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Windows,",-"030000007e0500000720000000000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,",-"03000000250900000017000000000000,Joypad Adapter,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows,",-"03000000bd12000003c0000000000000,Joypad Alpha Shock,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000ff1100004033000000000000,JPD FFB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a2,start:b15,x:b3,y:b0,platform:Windows,",-"03000000242f00002d00000000000000,JYS Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000242f00008a00000000000000,JYS Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,",-"03000000c4100000c082000000000000,KADE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000828200000180000000000000,Keio,a:b4,b:b5,back:b8,leftshoulder:b2,lefttrigger:b3,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b9,x:b0,y:b1,platform:Windows,",-"03000000790000000200000000000000,King PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,",-"03000000bd12000001e0000000000000,Leadership,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",-"030000006f0e00000103000000000000,Logic3,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000006f0e00000104000000000000,Logic3,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000008f0e00001300000000000000,Logic3,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"030000006d040000d1ca000000000000,Logitech ChillStream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006d040000d2ca000000000000,Logitech Cordless Precision,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006d04000011c2000000000000,Logitech Cordless Wingman,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b2,righttrigger:b7,rightx:a3,righty:a4,x:b4,platform:Windows,",-"030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006d0400001dc2000000000000,Logitech F310,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000006d04000018c2000000000000,Logitech F510,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006d0400001ec2000000000000,Logitech F510,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000006d04000019c2000000000000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006d0400001fc2000000000000,Logitech F710,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000006d0400001ac2000000000000,Logitech Precision,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"030000006d04000009c2000000000000,Logitech WingMan,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,",-"030000006d0400000bc2000000000000,Logitech WingMan Action Pad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b8,lefttrigger:a5~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:a2~,start:b8,x:b3,y:b4,platform:Windows,",-"030000006d0400000ac2000000000000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows,",-"03000000380700005645000000000000,Lynx,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000222200006000000000000000,Macally,a:b1,b:b2,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b33,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000380700003888000000000000,Mad Catz Arcade Fightstick TE S Plus PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000380700008532000000000000,Mad Catz Arcade Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000380700006352000000000000,Mad Catz CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000380700006652000000000000,Mad Catz CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",-"03000000380700005032000000000000,Mad Catz Fightpad Pro PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000380700005082000000000000,Mad Catz Fightpad Pro PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000380700008031000000000000,Mad Catz FightStick Alpha PS3 ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000003807000038b7000000000000,Mad Catz Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,",-"03000000380700008433000000000000,Mad Catz Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000380700008483000000000000,Mad Catz Fightstick TE S PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000380700008134000000000000,Mad Catz Fightstick TE2 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000380700008184000000000000,Mad Catz Fightstick TE2 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000380700006252000000000000,Mad Catz Micro CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",-"03000000380700008232000000000000,Mad Catz PlayStation Brawlpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000380700008731000000000000,Mad Catz PlayStation Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000003807000056a8000000000000,Mad Catz PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000380700001888000000000000,Mad Catz SFIV Fightstick PS3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"03000000380700008081000000000000,Mad Catz SFV Arcade Fightstick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000380700001847000000000000,Mad Catz Street Fighter 4 Xbox 360 FightStick,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,",-"03000000380700008034000000000000,Mad Catz TE2 PS3 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000380700008084000000000000,Mad Catz TE2 PS4 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000002a0600001024000000000000,Matricom,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,",-"030000009f000000adbb000000000000,MaxJoypad Virtual Controller,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",-"03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows,",-"03000000242f00003700000000000000,Mayflash F101,a:b1,b:b2,back:b8,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"03000000790000003018000000000000,Mayflash F300 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"03000000242f00003900000000000000,Mayflash F300 Elite Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000790000004418000000000000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",-"03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",-"03000000242f00007300000000000000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,",-"0300000079000000d218000000000000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000d620000010a7000000000000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000008f0e00001030000000000000,Mayflash Sega Saturn Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,platform:Windows,",-"0300000025090000e803000000000000,Mayflash Wii Classic Adapter,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,",-"03000000790000000318000000000000,Mayflash Wii DolphinBar,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,",-"03000000790000000018000000000000,Mayflash Wii U Pro Adapter,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000790000002418000000000000,Mega Drive Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b2,start:b9,x:b3,y:b4,platform:Windows,",-"0300000079000000ae18000000000000,Mega Drive Controller,a:b0,b:b1,back:b7,dpdown:b14,dpleft:b15,dpright:b13,dpup:b2,rightshoulder:b6,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,",-"03000000c0160000990a000000000000,Mega Drive Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,righttrigger:b2,start:b3,platform:Windows,",-"030000005e0400002800000000000000,Microsoft Dual Strike,a:b3,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,rightx:a0,righty:a1~,start:b5,x:b1,y:b0,platform:Windows,",-"030000005e0400000300000000000000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,",-"030000005e0400000700000000000000,Microsoft SideWinder,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,",-"030000005e0400000e00000000000000,Microsoft SideWinder Freestyle Pro,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b8,x:b3,y:b4,platform:Windows,",-"030000005e0400002700000000000000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Windows,",-"03000000280d00000202000000000000,Miller Lite Cantroller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b5,x:b2,y:b3,platform:Windows,",-"03000000ad1b000023f0000000000000,MLG,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a6,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,",-"03000000ad1b00003ef0000000000000,MLG Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,",-"03000000380700006382000000000000,MLG PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000ffff00000000000000000000,Mocute M053,a:b3,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b11,leftstick:b7,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b6,righttrigger:b4,rightx:a3,righty:a4,start:b8,x:b1,y:b0,platform:Windows,",-"03000000d6200000e589000000000000,Moga 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows,",-"03000000d62000007162000000000000,Moga Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows,",-"03000000d6200000ad0d000000000000,Moga Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000c62400002a89000000000000,Moga XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c62400002b89000000000000,Moga XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c62400001a89000000000000,Moga XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c62400001b89000000000000,Moga XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000efbe0000edfe000000000000,Monect Virtual Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows,",-"03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",-"03000000091200004488000000000000,MUSIA PlayStation 2 Input Display,a:b0,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:b11,rightx:a2,righty:a3,start:b5,x:b1,y:b3,platform:Windows,",-"03000000f70600000100000000000000,N64 Adaptoid,+rightx:b2,+righty:b1,-rightx:b4,-righty:b5,a:b0,b:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,platform:Windows,",-"030000006b140000010c000000000000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"030000006b1400001106000000000000,Nacon Revolution 3 PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000006b140000100d000000000000,Nacon Revolution Infinity PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006b140000080d000000000000,Nacon Revolution Unlimited Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000bd12000001c0000000000000,Nebular,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",-"03000000eb0300000000000000000000,NeGcon Adapter,a:a2,b:b13,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,lefttrigger:a4,leftx:a1,righttrigger:b11,start:b3,x:a3,y:b12,platform:Windows,",-"0300000038070000efbe000000000000,NEO SE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"0300000092120000474e000000000000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Windows,",-"03000000921200004b46000000000000,NES 2 port Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Windows,",-"03000000000f00000100000000000000,NES Controller,a:b1,b:b0,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows,",-"03000000921200004346000000000000,NES Controller,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows,",-"03000000790000004518000000000000,NEXILUX GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,",-"030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Windows,",-"03000000050b00000045000000000000,Nexus,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Windows,",-"03000000152000000182000000000000,NGDS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows,",-"030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"030000000d0500000308000000000000,Nostromo N45,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Windows,",-"030000007e0500001920000000000000,NSO N64 Controller,+rightx:b8,+righty:b2,-rightx:b3,-righty:b7,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Windows,",-"030000007e0500001720000000000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Windows,",-"03000000550900001472000000000000,NVIDIA Controller,a:b11,b:b10,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b5,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b4,righttrigger:a5,rightx:a3,righty:a6,start:b3,x:b9,y:b8,platform:Windows,",-"03000000550900001072000000000000,NVIDIA Shield,a:b9,b:b8,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b3,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b2,righttrigger:a4,rightx:a2,righty:a5,start:b0,x:b7,y:b6,platform:Windows,",-"030000005509000000b4000000000000,NVIDIA Virtual,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000120c00000288000000000000,Nyko Air Flo Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,",-"030000004b120000014d000000000000,Nyko Airflo,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,rightshoulder:b5,rightstick:a2,righttrigger:b7,start:b9,x:b2,y:b3,platform:Windows,",-"03000000d62000001d57000000000000,Nyko Airflo PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000791d00000900000000000000,Nyko Playpad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",-"03000000782300000a10000000000000,Onlive Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,platform:Windows,",-"030000000d0f00000401000000000000,Onyx,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000008916000001fd000000000000,Onza CE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a3,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000008916000000fd000000000000,Onza TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000d62000006d57000000000000,OPP PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006b14000001a1000000000000,Orange Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,",-"03000000362800000100000000000000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows,",-"03000000120c0000f60e000000000000,P4 Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,",-"03000000790000002201000000000000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"030000006f0e00008501000000000000,PDP Fightpad Pro,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b0,platform:Windows,",-"030000006f0e00000901000000000000,PDP Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"030000008f0e00004100000000000000,PlaySega,a:b1,b:b0,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b4,y:b3,platform:Windows,",-"03000000e30500009605000000000000,PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",-"030000004c050000da0c000000000000,PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,",-"03000000632500002306000000000000,PlayStation Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,",-"03000000f0250000c183000000000000,PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000d9040000160f000000000000,PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",-"030000004c0500003713000000000000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",-"03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"0300000062060000d570000000000000,PowerA PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000d620000013a7000000000000,PowerA Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006d04000084ca000000000000,Precision,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,",-"03000000d62000009557000000000000,Pro Elite PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000c62400001a53000000000000,Pro Ex Mini,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000d62000009f31000000000000,Pro Ex mini PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000d6200000c757000000000000,Pro Ex mini PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000110e000000000000,Pro5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000100800000100000000000000,PS1 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",-"030000008f0e00007530000000000000,PS1 Controller,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b1,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000100800000300000000000000,PS2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",-"03000000250900000088000000000000,PS2 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",-"03000000250900006888000000000000,PS2 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b6,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",-"03000000250900008888000000000000,PS2 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",-"03000000666600006706000000000000,PS2 Controller,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Windows,",-"030000006b1400000303000000000000,PS2 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"030000009d0d00001330000000000000,PS2 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"03000000151a00006222000000000000,PS2 Dual Plus Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",-"03000000120a00000100000000000000,PS3 Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",-"03000000120c00001307000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c00001cf1000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000f90e000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000250900000118000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",-"03000000250900000218000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",-"03000000250900000500000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows,",-"030000004c0500006802000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b10,lefttrigger:a3~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:a4~,rightx:a2,righty:a5,start:b8,x:b3,y:b0,platform:Windows,",-"030000004f1f00000800000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"03000000632500007505000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000888800000803000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,",-"03000000888800000804000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,leftshoulder:b10,leftstick:b1,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows,",-"030000008f0e00000300000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows,",-"030000008f0e00001431000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000ba2200002010000000000000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b2,platform:Windows,",-"03000000120c00000807000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000111e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000121e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000130e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000150e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000180e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000181e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000191e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c00001e0e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000a957000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000aa57000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000f21c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000f31c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000f41c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000f51c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120c0000f70e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000120e0000120c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000160e0000120c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000001a1e0000120c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000004c050000a00b000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,",-"030000004c050000cc09000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000004c050000e60c000000000000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,",-"03000000830500005020000000000000,PSX,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Windows,",-"03000000300f00000111000000000000,Qanba 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000300f00000211000000000000,Qanba 2P,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"03000000300f00000011000000000000,Qanba Arcade Stick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows,",-"03000000300f00001611000000000000,Qanba Arcade Stick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,",-"03000000222c00000025000000000000,Qanba Dragon Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000222c00000020000000000000,Qanba Drone Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows,",-"03000000300f00001211000000000000,Qanba Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000300f00001210000000000000,Qanba Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,",-"03000000341a00000104000000000000,Qanba Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,platform:Windows,",-"03000000222c00000223000000000000,Qanba Obsidian Arcade Stick PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000222c00000023000000000000,Qanba Obsidian Arcade Stick PS4,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000008a2400006682000000000000,R1 Mobile Controller,a:b3,b:b1,back:b7,leftx:a0,lefty:a1,start:b6,x:b4,y:b0,platform:Windows,",-"03000000086700006626000000000000,RadioShack,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows,",-"03000000ff1100004733000000000000,Ramox FPS Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows,",-"030000009b2800002300000000000000,Raphnet 3DO Adapter,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b2,start:b3,platform:Windows,",-"030000009b2800006900000000000000,Raphnet 3DO Adapter,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b2,start:b3,platform:Windows,",-"030000009b2800000800000000000000,Raphnet Dreamcast Adapter,a:b2,b:b1,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,lefttrigger:a2,leftx:a0,righttrigger:a3,righty:a1,start:b3,x:b10,y:b9,platform:Windows,",-"030000009b2800003200000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,",-"030000009b2800006000000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,",-"030000009b2800001800000000000000,Raphnet Jaguar Adapter,a:b2,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b10,start:b3,x:b11,y:b12,platform:Windows,",-"030000009b2800000200000000000000,Raphnet NES Adapter,a:b7,b:b6,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b4,platform:Windows,",-"030000009b2800004400000000000000,Raphnet PS1 and PS2 Adapter,a:b1,b:b2,back:b5,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b9,rightx:a3,righty:a4,start:b4,x:b0,y:b3,platform:Windows,",-"030000009b2800004300000000000000,Raphnet Saturn,a:b0,b:b1,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,",-"030000009b2800000500000000000000,Raphnet Saturn Adapter 2.0,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,",-"030000009b2800000300000000000000,Raphnet SNES Adapter,a:b0,b:b4,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,",-"030000009b2800005600000000000000,Raphnet SNES Adapter,a:b1,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Windows,",-"030000009b2800005700000000000000,Raphnet SNES Adapter,a:b1,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Windows,",-"030000009b2800001e00000000000000,Raphnet Vectrex Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a1,lefty:a2,x:b2,y:b3,platform:Windows,",-"030000009b2800002b00000000000000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b3,x:b0,y:b5,platform:Windows,",-"030000009b2800002c00000000000000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b3,x:b0,y:b5,platform:Windows,",-"03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000321500000204000000000000,Razer Panthera PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000321500000104000000000000,Razer Panthera PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000321500000010000000000000,Razer Raiju,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000321500000507000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000321500000707000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000321500000710000000000000,Razer Raiju TE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000321500000a10000000000000,Razer Raiju TE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000321500000410000000000000,Razer Raiju UE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000321500000910000000000000,Razer Raiju UE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000321500000011000000000000,Razer Raion PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000321500000009000000000000,Razer Serval,+lefty:+a2,-lefty:-a1,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,leftx:a0,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000921200004547000000000000,Retro Bit Sega Genesis Controller Adapter,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b6,x:b3,y:b4,platform:Windows,",-"03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000830500006020000000000000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,",-"03000000bd12000013d0000000000000,Retrolink Sega Saturn Classic Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,lefttrigger:b6,rightshoulder:b2,righttrigger:b7,start:b8,x:b3,y:b4,platform:Windows,",-"03000000bd12000015d0000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,",-"0300000000f000000300000000000000,RetroUSB RetroPad,a:b1,b:b5,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,",-"0300000000f00000f100000000000000,RetroUSB Super RetroPort,a:b1,b:b5,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,",-"03000000830500000960000000000000,Revenger,a:b0,b:b1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b3,x:b4,y:b5,platform:Windows,",-"030000006b140000010d000000000000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000006b140000020d000000000000,Revolution Pro Controller 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000006b140000130d000000000000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000006f0e00001f01000000000000,Rock Candy,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000006f0e00004601000000000000,Rock Candy,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000c6240000fefa000000000000,Rock Candy Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000006f0e00001e01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006f0e00002801000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006f0e00002f01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006f0e00008701000000000000,Rock Candy Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000050b0000e318000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,",-"03000000050b0000e518000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,",-"03000000050b00005819000000000000,ROG Chakram Core,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,",-"03000000050b0000181a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,",-"03000000050b00001a1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,",-"03000000050b00001c1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,",-"030000004f04000001d0000000000000,Rumble Force,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,",-"030000008916000000fe000000000000,Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000c6240000045d000000000000,Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000a30600001af5000000000000,Saitek Cyborg,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",-"03000000a306000023f6000000000000,Saitek Cyborg V.1 Game,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",-"03000000300f00001201000000000000,Saitek Dual Analog,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",-"03000000a30600000701000000000000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Windows,",-"03000000a30600000cff000000000000,Saitek P2500 Force Rumble,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b0,y:b1,platform:Windows,",-"03000000a30600000d5f000000000000,Saitek P2600,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Windows,",-"03000000a30600000dff000000000000,Saitek P2600,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b8,x:b0,y:b3,platform:Windows,",-"03000000a30600000c04000000000000,Saitek P2900,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",-"03000000a306000018f5000000000000,Saitek P3200,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",-"03000000300f00001001000000000000,Saitek P480 Rumble,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",-"03000000a30600000901000000000000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b8,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b5,rightx:a3,righty:a2,x:b0,y:b1,platform:Windows,",-"03000000a30600000b04000000000000,Saitek P990,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",-"03000000a30600002106000000000000,Saitek PS1000 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",-"03000000a306000020f6000000000000,Saitek PS2700 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",-"03000000300f00001101000000000000,Saitek Rumble,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",-"03000000e804000000a0000000000000,Samsung EIGP20,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000c01100000252000000000000,Sanwa Easy Grip,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,",-"03000000c01100004350000000000000,Sanwa Micro Grip P3,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,x:b3,y:b2,platform:Windows,",-"03000000411200004550000000000000,Sanwa Micro Grip Pro,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a1,righty:a2,start:b9,x:b1,y:b3,platform:Windows,",-"03000000c01100004150000000000000,Sanwa Micro Grip Pro,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,",-"03000000c01100004450000000000000,Sanwa Online Grip,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b11,righttrigger:b9,rightx:a3,righty:a2,start:b14,x:b3,y:b4,platform:Windows,",-"03000000730700000401000000000000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows,",-"03000000830500006120000000000000,Sanwa Smart Grip II,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,x:b1,y:b3,platform:Windows,",-"03000000c01100000051000000000000,Satechi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",-"030000004f04000028b3000000000000,Score A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000952e00002577000000000000,Scuf PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000a30c00002500000000000000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Windows,",-"03000000a30c00002400000000000000,Sega Mega Drive Mini 6B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,",-"0300000000050000289b000000000000,Sega Saturn Adapter,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,",-"0300000000f000000800000000000000,Sega Saturn Controller,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b7,righttrigger:b3,start:b0,x:b5,y:b6,platform:Windows,",-"03000000730700000601000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,",-"03000000b40400000a01000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,",-"030000003b07000004a1000000000000,SFX,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Windows,",-"03000000f82100001900000000000000,Shogun Bros Chameleon X1,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",-"03000000120c00001c1e000000000000,SnakeByte 4S PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"0300000003040000c197000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,",-"0300000081170000960a000000000000,SNES Controller,a:b4,b:b0,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b5,y:b1,platform:Windows,",-"03000000811700009d0a000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,",-"030000008b2800000300000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,",-"03000000921200004653000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,",-"03000000ff000000cb01000000000000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,",-"03000000341a00000208000000000000,Speedlink 6555,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows,",-"03000000341a00000908000000000000,Speedlink 6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"03000000380700001722000000000000,Speedlink Competition Pro,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,x:b2,y:b3,platform:Windows,",-"030000008f0e00000800000000000000,Speedlink Strike FX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000c01100000591000000000000,Speedlink Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000d11800000094000000000000,Stadia Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b11,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,",-"03000000de280000fc11000000000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000de280000ff11000000000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000120c0000160e000000000000,Steel Play Metaltech PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000110100001914000000000000,SteelSeries,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000381000001214000000000000,SteelSeries Free,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,",-"03000000110100003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000381000003014000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000381000003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000381000001814000000000000,SteelSeries Stratus XL,a:b0,b:b1,back:b18,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b19,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b2,y:b3,platform:Windows,",-"03000000790000001c18000000000000,STK 7024X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000380700003847000000000000,Street Fighter Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,start:b7,x:b2,y:b3,platform:Windows,",-"030000001f08000001e4000000000000,Super Famicom Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,",-"03000000790000000418000000000000,Super Famicom Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b33,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,",-"03000000341200001300000000000000,Super Racer,a:b2,b:b3,back:b8,leftshoulder:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b7,x:b0,y:b1,platform:Windows,",-"03000000d620000011a7000000000000,Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000000d0f0000f600000000000000,Switch Hori Pad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"03000000457500002211000000000000,Szmy Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000004f0400000ab1000000000000,T16000M,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b10,x:b2,y:b3,platform:Windows,",-"030000000d0f00007b00000000000000,TAC GEAR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000e40a00000207000000000000,Taito Egret II Mini Controller,a:b4,b:b2,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b9,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Windows,",-"03000000d814000001a0000000000000,TE Kitty,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000fa1900000706000000000000,Team 5,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000b50700001203000000000000,Techmobility X6-38V,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",-"03000000ba2200000701000000000000,Technology Innovation PS2 Adapter,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b2,platform:Windows,",-"03000000c61100001000000000000000,Tencent Xianyou Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows,",-"03000000790000002601000000000000,TGZ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows,",-"030000004f04000015b3000000000000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,",-"030000004f04000023b3000000000000,Thrustmaster Dual Trigger PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000004f0400000ed0000000000000,ThrustMaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000004f04000008d0000000000000,ThrustMaster Ferrari 150 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows,",-"030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,",-"030000004f04000003d0000000000000,ThrustMaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000004f04000009d0000000000000,ThrustMaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"030000006d04000088ca000000000000,Thunderpad,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,",-"03000000666600000288000000000000,TigerGame PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",-"03000000666600000488000000000000,TigerGame PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",-"030000004f04000007d0000000000000,TMini,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000571d00002100000000000000,Tomee NES Controller Adapter,a:b1,b:b0,back:b2,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,start:b3,platform:Windows,",-"03000000571d00002000000000000000,Tomee SNES Controller Adapter,a:b0,b:b1,back:b6,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,",-"03000000d62000006000000000000000,Tournament PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000c01100000055000000000000,Tronsmart,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"030000005f140000c501000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000b80500000210000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"030000004f04000087b6000000000000,TWCS Throttle,dpdown:b8,dpleft:b9,dpright:b7,dpup:b6,leftstick:b5,lefttrigger:-a5,leftx:a0,lefty:a1,righttrigger:+a5,platform:Windows,",-"03000000411200000450000000000000,Twin Shock,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a4,start:b11,x:b3,y:b0,platform:Windows,",-"03000000d90400000200000000000000,TwinShock PS2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",-"03000000151900005678000000000000,Uniplay U6,a:b0,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b10,x:b3,y:b4,platform:Windows,",-"03000000101c0000171c000000000000,uRage Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"030000000b0400003065000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows,",-"03000000242f00006e00000000000000,USB Controller,a:b1,b:b4,back:b10,leftshoulder:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b7,rightx:a2,righty:a5,start:b11,x:b0,y:b3,platform:Windows,",-"03000000300f00000701000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",-"03000000341a00002308000000000000,USB Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"03000000666600000188000000000000,USB Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",-"030000006b1400000203000000000000,USB Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"03000000790000000a00000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,",-"03000000b404000081c6000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows,",-"03000000b50700001503000000000000,USB Controller,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",-"03000000bd12000012d0000000000000,USB Controller,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,",-"03000000ff1100004133000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",-"03000000632500002305000000000000,USB Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",-"03000000790000001a18000000000000,Venom,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",-"03000000790000001b18000000000000,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"030000006f0e00000302000000000000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"030000006f0e00000702000000000000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",-"0300000034120000adbe000000000000,vJoy Device,a:b0,b:b1,back:b15,dpdown:b6,dpleft:b7,dpright:b8,dpup:b5,guide:b16,leftshoulder:b9,leftstick:b13,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b14,righttrigger:b12,rightx:a3,righty:a4,start:b4,x:b2,y:b3,platform:Windows,",-"03000000120c0000ab57000000000000,Warrior Joypad JS083,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"030000007e0500003003000000000000,Wii U Pro,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,leftshoulder:b6,leftstick:b11,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b12,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,",-"0300000032150000030a000000000000,Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"0300000032150000140a000000000000,Wolverine,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000002e160000efbe000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,rightshoulder:b5,righttrigger:b11,start:b7,x:b2,y:b3,platform:Windows,",-"03000000380700001647000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000380700002045000000000000,Xbox 360 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"03000000380700002644000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a2,righty:a5,start:b8,x:b2,y:b3,platform:Windows,",-"03000000380700002647000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000003807000026b7000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000380700003647000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a7,righty:a5,start:b7,x:b2,y:b3,platform:Windows,",-"030000005e0400001907000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000005e0400008e02000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000005e0400009102000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000ad1b000000fd000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000ad1b000001fd000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000ad1b000016f0000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000ad1b00008e02000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000c62400000053000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000c6240000fdfa000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000380700002847000000000000,Xbox 360 Fightpad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000005e040000a102000000000000,Xbox 360 Wireless Receiver,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000120c00000a88000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a2,righty:a4,start:b6,x:b2,y:b3,platform:Windows,",-"03000000120c00001088000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2~,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5~,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000002a0600002000000000000000,Xbox Controller,a:b0,b:b1,back:b13,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b5,leftstick:b14,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b15,righttrigger:b7,rightx:a2,righty:a5,start:b12,x:b2,y:b3,platform:Windows,",-"03000000300f00008888000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:b13,dpleft:b10,dpright:b11,dpup:b12,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,",-"03000000380700001645000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,",-"03000000380700002645000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000380700003645000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,",-"03000000380700008645000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000005e0400000202000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,",-"030000005e0400008502000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000005e0400008702000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b7,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,",-"030000005e0400008902000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b10,leftstick:b8,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b9,righttrigger:b4,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,",-"030000000d0f00006300000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000005e0400000c0b000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000005e040000d102000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000005e040000dd02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000005e040000e002000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000005e040000e302000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000005e040000ea02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000005e040000fd02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000005e040000ff02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000006f0e0000a802000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000006f0e0000c802000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000c62400003a54000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000005e040000130b000000000000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"03000000341a00000608000000000000,Xeox,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"03000000450c00002043000000000000,Xeox SL6556BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",-"030000006f0e00000300000000000000,XGear,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",-"03000000172700004431000000000000,Xiaomi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",-"03000000172700003350000000000000,Xiaomi XMGP01YM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000bc2000005060000000000000,Xiaomi XMGP01YM,+lefty:+a2,+righty:+a5,-lefty:-a1,-righty:-a4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,start:b11,x:b3,y:b4,platform:Windows,",-"03000000786901006e70000000000000,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",-"030000007d0400000340000000000000,Xterminator Digital Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:-a4,lefttrigger:+a4,leftx:a0,lefty:a1,paddle1:b7,paddle2:b6,rightshoulder:b5,rightstick:b9,righttrigger:b2,rightx:a3,righty:a5,start:b8,x:b3,y:b4,platform:Windows,",-"03000000790000004f18000000000000,ZDT Android Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",-"03000000120c00000500000000000000,Zeroplus Adapter,a:b2,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:b5,rightx:a3,righty:a2,start:b8,x:b3,y:b0,platform:Windows,",-"03000000120c0000101e000000000000,Zeroplus P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",-"78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",-"78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",-"78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",-"78696e70757404000000000000000000,XInput Flight Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",-"78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",-"78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",-"78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",-#endif // GLFW_BUILD_WIN32_MAPPINGS--#if defined(GLFW_BUILD_COCOA_MAPPINGS)-"030000008f0e00000300000009010000,2 In 1 Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,",-"03000000c82d00000031000001000000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"03000000c82d00000531000000020000,8BitDo Adapter 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"03000000c82d00000951000000010000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Mac OS X,",-"03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00001251000000010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00001251000000020000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00001151000000010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00001151000000020000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000a30c00002400000006020000,8BitDo M30,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,guide:b9,leftshoulder:b6,lefttrigger:b5,rightshoulder:b4,righttrigger:b7,start:b8,x:b3,y:b0,platform:Mac OS X,",-"03000000c82d00000151000000010000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"03000000c82d00000650000001000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Mac OS X,",-"03000000c82d00005106000000010000,8BitDo M30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b2,leftshoulder:b6,lefttrigger:a5,rightshoulder:b7,righttrigger:a4,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00000451000000010000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Mac OS X,",-"03000000c82d00001590000001000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"030000003512000012ab000001000000,8BitDo NES30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d000012ab000001000000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,",-"03000000c82d00002028000000010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,",-"03000000022000000090000001000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000203800000900000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00000190000001000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00000751000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"03000000c82d00000851000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"03000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00000660000000020000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00000131000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00000231000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00000331000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00000431000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00002867000000010000,8BitDo S30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b3,y:b4,platform:Mac OS X,",-"03000000102800000900000000000000,8BitDo SFC30 Joystick,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00000351000000010000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00001290000001000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00004028000000010000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00000260000001000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000a00500003232000008010000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,",-"03000000a00500003232000009010000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,",-"03000000c82d00001890000001000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a31,start:b11,x:b4,y:b3,platform:Mac OS X,",-"03000000491900001904000001010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Mac OS X,",-"03000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,",-"03000000a30c00002700000003030000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",-"03000000a30c00002800000003030000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",-"03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,",-"03000000050b00000579000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b42,paddle1:b9,paddle2:b11,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,",-"03000000050b00000679000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b23,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,",-"03000000c62400001a89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,",-"03000000c62400001b89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"03000000d62000002a79000000010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000120c0000200e000000010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000120c0000210e000000010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000d8140000cecf000000000000,Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,",-"03000000a306000022f6000001030000,Cyborg V3 Rumble Pad PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000791d00000103000009010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,",-"030000006e0500000720000010020000,Elecom JC-W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Mac OS X,",-"030000006f0e00008401000003010000,Faceoff Premiere Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,",-"03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle3:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,platform:Mac OS X,",-"03000000790000004618000000010000,GameCube Controller Adapter,a:b4,b:b0,dpdown:b56,dpleft:b60,dpright:b52,dpup:b48,lefttrigger:a12,leftx:a0,lefty:a4,rightshoulder:b28,righttrigger:a16,rightx:a20,righty:a8,start:b36,x:b8,y:b12,platform:Mac OS X,",-"03000000ad1b000001f9000000000000,Gamestop BB070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,",-"03000000c01100000140000000010000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000006f0e00000102000000000000,GameStop Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"030000007d0400000540000001010000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000280400000140000000020000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000008f0e00000300000007010000,GreenAsia Joystick,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Mac OS X,",-"030000000d0f00002d00000000100000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000000d0f00005f00000000000000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000000d0f00005f00000000010000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000000d0f00005e00000000000000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000000d0f00005e00000000010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000000d0f00008400000000010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000000d0f00008500000000010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000000d0f00008800000000010000,Hori Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000000d0f00008700000000010000,Hori Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000000d0f00004d00000000000000,Hori Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000000d0f00003801000008010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Mac OS X,",-"030000000d0f00009200000000010000,Hori Pokken Tournament DX Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000000d0f00006e00000000010000,Horipad 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000000d0f00006600000000010000,Horipad 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000000d0f00006600000000000000,Horipad FPS Plus 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000000d0f0000ee00000000010000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000008f0e00001330000011010000,HuiJia SNES Controller,a:b4,b:b2,back:b16,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b12,rightshoulder:b14,start:b18,x:b6,y:b0,platform:Mac OS X,",-"03000000790000004e95000000010000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Mac OS X,",-"03000000830500006020000000000000,iBuffalo Gamepad,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,",-"03000000ef0500000300000000020000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Mac OS X,",-"03000000fd0500000030000010010000,Interact GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Mac OS X,",-"030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Mac OS X,",-"030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Mac OS X,",-"03000000242f00002d00000007010000,JYS Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,",-"030000006d04000019c2000000000000,Logitech Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000006d04000016c2000000020000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000006d04000016c2000000030000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000006d04000016c2000014040000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000006d04000016c2000000000000,Logitech F310,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000006d04000018c2000000000000,Logitech F510,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000006d04000019c2000005030000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000006d0400001fc2000000000000,Logitech F710,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"030000006d04000018c2000000010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3~,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000380700005032000000010000,Mad Catz PS3 Fightpad Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000380700008433000000010000,Mad Catz PS3 Fightstick TE S+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000380700005082000000010000,Mad Catz PS4 Fightpad Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000380700008483000000010000,Mad Catz PS4 Fightstick TE S+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000790000000600000007010000,Marvo GT-004,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,",-"03000000790000004318000000010000,Mayflash GameCube Adapter,a:b4,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a12,leftx:a0,lefty:a4,rightshoulder:b28,righttrigger:a16,rightx:a20,righty:a8,start:b36,x:b8,y:b12,platform:Mac OS X,",-"03000000790000004418000000010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000242f00007300000000020000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Mac OS X,",-"0300000079000000d218000026010000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,",-"03000000d620000010a7000003010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"0300000025090000e803000000000000,Mayflash Wii Classic Adapter,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X,",-"03000000790000000318000000010000,Mayflash Wii DolphinBar,a:b8,b:b12,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b44,leftshoulder:b16,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b4,platform:Mac OS X,",-"03000000790000000018000000000000,Mayflash Wii U Pro Adapter,a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,",-"03000000790000000018000000010000,Mayflash Wii U Pro Adapter,a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,",-"030000005e0400002800000002010000,Microsoft Dual Strike,a:b3,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,rightx:a0,righty:a1~,start:b5,x:b1,y:b0,platform:Mac OS X,",-"030000005e0400002700000001010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Mac OS X,",-"03000000d62000007162000001000000,Moga Pro 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,",-"03000000c62400002a89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"03000000c62400002b89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"03000000632500007505000000020000,NeoGeo mini PAD Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b2,y:b3,platform:Mac OS X,",-"03000000921200004b46000003020000,NES 2-port Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Mac OS X,",-"030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Mac OS X,",-"03000000d620000011a7000000020000,Nintendo Switch Core Plus Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000d620000011a7000010050000,Nintendo Switch PowerA Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,",-"030000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,",-"030000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Mac OS X,",-"030000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Mac OS X,",-"03000000550900001472000025050000,NVIDIA Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Mac OS X,",-"030000006f0e00000901000002010000,PDP Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000008f0e00000300000000000000,Piranha Xtreme PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,",-"030000004c050000da0c000000010000,PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",-"030000004c0500003713000000010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000d62000006dca000000010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000100800000300000006010000,PS2 Adapter,a:b2,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,",-"030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,",-"030000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,",-"030000004c0500006802000072050000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,",-"030000004c050000a00b000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,",-"050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,",-"03000000222c00000225000000010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000222c00000020000000010000,Qanba Drone Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"03000000321500000204000000010000,Razer Panthera PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000321500000104000000010000,Razer Panthera PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000321500000010000000010000,Razer Raiju,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000321500000507000001010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"03000000321500000011000000010000,Razer Raion PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000321500000009000000020000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,",-"030000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,",-"0300000032150000030a000000000000,Razer Wildcat,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"03000000632500008005000000010000,Redgear,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,",-"030000000d0f0000c100000072050000,Retro Bit Sega Genesis 6B Controller,a:b2,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b8,rightshoulder:b6,righttrigger:b7,start:b9,x:b3,y:b0,platform:Mac OS X,",-"03000000921200004547000000020000,Retro Bit Sega Genesis Controller Adapter,a:b0,b:b2,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,lefttrigger:b14,rightshoulder:b10,righttrigger:b4,start:b12,x:b6,y:b8,platform:Mac OS X,",-"03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000790000001100000005010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000830500006020000000010000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Mac OS X,",-"03000000790000001100000006010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",-"030000006b140000010d000000010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000006b140000130d000000010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000c6240000fefa000000000000,Rock Candy PS3,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"03000000730700000401000000010000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Mac OS X,",-"03000000a30c00002500000006020000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Mac OS X,",-"03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X,",-"03000000b40400000a01000000000000,Sega Saturn,a:b0,b:b1,back:b5,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b2,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X,",-"030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,",-"0300000000f00000f100000000000000,SNES RetroPort,a:b2,b:b3,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,rightshoulder:b7,start:b6,x:b0,y:b1,platform:Mac OS X,",-"030000004c050000a00b000000000000,Sony DualShock 4 Adapter,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000d11800000094000000010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,",-"030000005e0400008e02000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,",-"03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,",-"03000000381000002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,",-"05000000484944204465766963650000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,",-"050000004e696d6275732b0000000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,",-"050000004e696d6275732b008b000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,",-"05000000556e6b6e6f776e2048494400,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,",-"03000000381000003014000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"03000000381000003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"03000000110100001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,",-"03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,",-"030000000d0f0000f600000000010000,Switch Hori Pad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,",-"03000000457500002211000000010000,SZMY Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X,",-"030000004f0400000ed0000000020000,ThrustMaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X,",-"03000000571d00002100000021000000,Tomee NES Controller Adapter,a:b1,b:b0,back:b2,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,start:b3,platform:Mac OS X,",-"03000000bd12000015d0000000010000,Tomee Retro Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",-"03000000bd12000015d0000000000000,Tomee SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",-"03000000571d00002000000021000000,Tomee SNES Controller Adapter,a:b0,b:b1,back:b6,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Mac OS X,",-"030000005f140000c501000000020000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,",-"03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X,",-"030000006f0e00000302000025040000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",-"030000006f0e00000702000003060000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",-"050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X,",-"050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X,",-"030000005e0400008e02000000000000,Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"030000006f0e00000104000000000000,Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"03000000c6240000045d000000000000,Xbox 360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"030000005e040000050b000003090000,Xbox Elite Controller Series 2,a:b0,b:b1,back:b31,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b53,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"030000005e040000130b000011050000,Xbox One Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"030000005e040000200b000011050000,Xbox One Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"030000005e040000d102000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"030000005e040000dd02000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"030000005e040000e002000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,",-"030000005e040000e002000003090000,Xbox One Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"030000005e040000e302000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"030000005e040000ea02000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"030000005e040000fd02000003090000,Xbox One Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"03000000c62400003a54000000000000,Xbox One PowerA Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",-"030000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"030000005e040000130b000009050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"030000005e040000130b000013050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",-"03000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X,",-"03000000120c0000100e000000010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-"03000000120c0000101e000000010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",-#endif // GLFW_BUILD_COCOA_MAPPINGS--#if defined(GLFW_BUILD_LINUX_MAPPINGS)-"030000005e0400008e02000020010000,8BitDo Adapter,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000c82d00000031000011010000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"03000000c82d00000951000000010000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux,",-"03000000021000000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c82d00001251000011010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"05000000c82d00001251000000010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c82d00001151000011010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"05000000c82d00001151000000010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c82d00000151000000010000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"03000000c82d00000650000011010000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,platform:Linux,",-"05000000c82d00005106000000010000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Linux,",-"03000000c82d00000451000000010000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux,",-"03000000c82d00001590000011010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"05000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"03000000008000000210000011010000,8BitDo NES30,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",-"03000000c82d00000310000011010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux,",-"05000000c82d00008010000000010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux,",-"03000000022000000090000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c82d00000190000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"05000000203800000900000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"05000000c82d00002038000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c82d00000751000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"05000000c82d00000851000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"03000000c82d00000660000011010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"05000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c82d00000131000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c82d00000231000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c82d00000331000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c82d00000431000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c82d00002867000000010000,8BitDo S30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b3,y:b4,platform:Linux,",-"05000000c82d00000060000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"05000000c82d00000061000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"030000003512000012ab000010010000,8BitDo SFC30,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux,",-"030000003512000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c82d000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,",-"05000000102800000900000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,",-"05000000c82d00003028000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,",-"05000000c82d00000351000000010000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c82d00000160000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c82d00001290000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux,",-"05000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"05000000c82d00006228000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c82d00000260000011010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"05000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"05000000202800000900000000010000,8BitDo SNES30,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,",-"05000000a00500003232000001000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,",-"05000000a00500003232000008010000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,",-"03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,",-"050000005e040000e002000030110000,8BitDo Zero 2,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,",-"05000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",-"03000000c01100000355000011010000,Acrux Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000006f0e00003901000000430000,Afterglow Prismatic Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006f0e00003901000013020000,Afterglow Prismatic Controller 048-007-NA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006f0e00001302000000010000,Afterglow Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006f0e00003901000020060000,Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000100000008200000011010000,Akishop Customs PS360,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",-"030000007c1800000006000010010000,Alienware Dual Compatible Game PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Linux,",-"05000000491900000204000021000000,Amazon Fire Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"03000000491900001904000011010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Linux,",-"05000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,",-"03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",-"03000000a30c00002700000011010000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,",-"03000000a30c00002800000011010000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,",-"05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,",-"05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,",-"03000000050b00000579000011010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b36,paddle1:b52,paddle2:b53,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"05000000050b00000679000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b21,paddle1:b22,paddle2:b23,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"03000000503200000110000000000000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,",-"03000000503200000110000011010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,",-"05000000503200000110000000000000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,",-"05000000503200000110000044010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,",-"05000000503200000110000046010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,",-"03000000503200000210000000000000,Atari Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Linux,",-"03000000503200000210000011010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,",-"05000000503200000210000000000000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,",-"05000000503200000210000045010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,",-"05000000503200000210000046010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,",-"05000000503200000210000047010000,Atari VCS Modern Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:-a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Linux,",-"03000000c62400001b89000011010000,BDA MOGA XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"03000000d62000002a79000011010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"03000000c21100000791000011010000,Be1 GC101 Controller 1.03,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"03000000c31100000791000011010000,Be1 GC101 Controller 1.03,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"030000005e0400008e02000003030000,Be1 GC101 Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"05000000bc2000000055000001000000,BETOP AX1 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"03000000bc2000006412000011010000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b30,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"030000006b1400000209000011010000,Bigben,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000666600006706000000010000,Boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux,",-"03000000120c0000200e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"03000000120c0000210e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000120c0000f70e000011010000,Brook Universal Fighting Board,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",-"03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux,",-"03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux,",-"03000000a306000022f6000011010000,Cyborg V3 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,",-"03000000791d00000103000010010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000c11100000191000011010000,EasySMX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"03000000242f00009100000000010000,EasySMX ESM-9101,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006e0500000320000010010000,Elecom U3613M,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,",-"030000006e0500000720000010010000,Elecom W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux,",-"030000007d0400000640000010010000,Eliminator AfterShock,a:b1,b:b2,back:b9,dpdown:+a3,dpleft:-a5,dpright:+a5,dpup:-a3,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a4,righty:a2,start:b8,x:b0,y:b3,platform:Linux,",-"03000000430b00000300000000010000,EMS Production PS2 Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",-"03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",-"03000000ac0500005b05000010010000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"03000000558500001b06000010010000,GameSir G4 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"05000000ac0500002d0200001b010000,GameSir G4s,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b33,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"03000000bc2000005656000011010000,GameSir T4w,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",-"030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000008f0e00000800000010010000,Gasia PlayStation Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"03000000451300000010000010010000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",-"03000000f0250000c183000010010000,Goodbetterbest Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"0300000079000000d418000000010000,GPD Win 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000007d0400000540000000010000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",-"03000000280400000140000000010000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",-"030000008f0e00000610000000010000,GreenAsia Electronics Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux,",-"030000008f0e00001200000010010000,GreenAsia Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,",-"0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",-"03000000f0250000c383000010010000,GT VX2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"06000000adde0000efbe000002010000,Hidromancer Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000d81400000862000011010000,HitBox PS3 PC Analog Mode,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux,",-"03000000c9110000f055000011010000,HJC Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",-"03000000632500002605000010010000,HJDX,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"030000000d0f00000d00000000010000,Hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux,",-"030000000d0f00006d00000020010000,Hori EDGE 301,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:+a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000000d0f00005f00000011010000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000000d0f00005e00000011010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"030000000d0f00005001000009040000,Hori Fighting Commander OCTA Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000000d0f00008500000010010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000000d0f00008600000002010000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",-"030000000d0f00008800000011010000,Hori Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",-"030000000d0f00008700000011010000,Hori Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,rightshoulder:b5,rightstick:b11,righttrigger:a4,start:b9,x:b0,y:b3,platform:Linux,",-"030000000d0f00001000000011010000,Hori Fightstick 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",-"03000000ad1b000003f5000033050000,Hori Fightstick VX,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b8,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,",-"030000000d0f00004d00000011010000,Hori Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000000d0f00003801000011010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Linux,",-"030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",-"030000000d0f0000aa00000011010000,Hori Real Arcade Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"030000000d0f00001100000011010000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000000d0f00002200000011010000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",-"030000000d0f00006a00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"030000000d0f00006b00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000000d0f00001600000000010000,Hori Real Arcade Pro EXSE,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,",-"030000000d0f00006e00000011010000,Horipad 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000000d0f00006600000011010000,Horipad 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"030000000d0f0000ee00000011010000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"030000000d0f00006700000001010000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000000d0f0000c100000011010000,Horipad S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"050000000d0f0000f600000001000000,Horipad Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",-"03000000341a000005f7000010010000,HuiJia GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,",-"030000008f0e00001330000010010000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Linux,",-"03000000242e00008816000001010000,Hyperkin X91,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,",-"050000006964726f69643a636f6e0000,idroidcon Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000b50700001503000010010000,Impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,",-"03000000d80400008200000003000000,IMS PCU0,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux,",-"03000000120c00000500000010010000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux,",-"03000000ef0500000300000000010000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux,",-"03000000fd0500000030000000010000,InterAct GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Linux,",-"03000000fd0500002a26000000010000,InterAct HammerHead FX,a:b3,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b2,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,",-"0500000049190000020400001b010000,Ipega PG 9069,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b161,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"03000000632500007505000011010000,Ipega PG 9099,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"0500000049190000030400001b010000,Ipega PG9099,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"05000000491900000204000000000000,Ipega PG9118,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"03000000300f00001001000010010000,Jess Tech Dual Analog Rumble,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,",-"03000000300f00000b01000010010000,Jess Tech GGE909 PC Recoil,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",-"03000000ba2200002010000001010000,Jess Technology Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",-"030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux,",-"050000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux,",-"030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux,",-"050000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux,",-"03000000bd12000003c0000010010000,Joypad Alpha Shock,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000242f00002d00000011010000,JYS Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"03000000242f00008a00000011010000,JYS Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux,",-"030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006d040000d1ca000000000000,Logitech Chillstream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000006d0400001dc2000014400000,Logitech F310,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006d0400001ec2000019200000,Logitech F510,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006d0400001ec2000020200000,Logitech F510,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006d04000019c2000011010000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000006d0400001fc2000005030000,Logitech F710,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux,",-"030000006d0400000ac2000010010000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux,",-"05000000380700006652000025010000,Mad Catz CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000380700008532000010010000,Mad Catz Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",-"03000000380700005032000011010000,Mad Catz Fightpad Pro PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000380700005082000011010000,Mad Catz Fightpad Pro PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux,",-"03000000380700008034000011010000,Mad Catz Fightstick PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000380700008084000011010000,Mad Catz Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"03000000380700008433000011010000,Mad Catz Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000380700008483000011010000,Mad Catz Fightstick TE S PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"03000000380700001888000010010000,Mad Catz Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000380700003888000010010000,Mad Catz Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000380700001647000010040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000380700003847000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",-"03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000120c00000500000000010000,Manta Dualshock 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,",-"03000000790000004318000010010000,Mayflash GameCube Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,",-"03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,",-"03000000242f00007300000011010000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux,",-"0300000079000000d218000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000d620000010a7000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000242f0000f700000001010000,Mayflash Magic S Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"0300000025090000e803000001010000,Mayflash Wii Classic Adapter,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,",-"03000000790000000318000011010000,Mayflash Wii DolphinBar,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux,",-"03000000b50700001203000010010000,Mega World Logic 3 Controller,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,",-"03000000780000000600000010010000,Microntek Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,",-"030000005e0400002800000000010000,Microsoft Dual Strike,a:b3,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,rightx:a0,righty:a1~,start:b5,x:b1,y:b0,platform:Linux,",-"030000005e0400000e00000000010000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,",-"030000005e0400000700000000010000,Microsoft SideWinder Gamepad,a:b0,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Linux,",-"030000005e0400002700000000010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Linux,",-"030000005e0400008502000000010000,Microsoft Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,",-"030000005e0400008e02000001000000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.1,dpleft:h0.2,dpright:h0.8,dpup:h0.4,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e0400008e02000004010000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e0400008e02000056210000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e0400008e02000062230000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e040000120b00000b050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e040000d102000001010000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e040000d102000003020000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"060000005e040000120b000009050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e040000dd02000003020000,Microsoft Xbox One 2015,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e040000e302000003020000,Microsoft Xbox One Elite,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e040000000b000008040000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"050000005e040000050b000003090000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"030000005e040000ea02000008040000,Microsoft Xbox One S,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e0400008902000021010000,Microsoft Xbox pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,",-"03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,",-"050000004d4f435554452d3035335800,Mocute 053X,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",-"050000004d4f435554452d3035305800,Mocute 054X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"05000000d6200000e589000001000000,Moga 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,",-"05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,",-"05000000d62000007162000001000000,Moga Pro 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,",-"03000000c62400002b89000011010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"05000000c62400002a89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"05000000c62400001a89000000010000,MOGA XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"03000000250900006688000000010000,MP8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,",-"030000005e0400008e02000010020000,MSI GC20 V2,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006b1400000906000014010000,Nacon Asymmetric Wireless PS4 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006b140000010c000010010000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",-"03000000853200000706000012010000,Nacon GC-100,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000004f1f00000800000011010000,NeoGeo PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",-"0300000092120000474e000000010000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Linux,",-"03000000790000004518000010010000,Nexilux GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,",-"030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Linux,",-"060000007e0500003713000000000000,Nintendo 3DS,a:b0,b:b1,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,",-"030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux,",-"03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b2,y:b3,platform:Linux,",-"060000007e0500000620000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,",-"060000007e0500000820000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,",-"050000004c69632050726f20436f6e00,Nintendo Switch Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",-"050000007e0500000620000001800000,Nintendo Switch Left Joy-Con,a:b16,b:b15,back:b4,leftshoulder:b6,leftstick:b12,leftx:a1,lefty:a0~,rightshoulder:b8,start:b9,x:b14,y:b17,platform:Linux,",-"03000000d620000013a7000011010000,Nintendo Switch PowerA Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000d620000011a7000011010000,Nintendo Switch PowerA Core Plus Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,",-"050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",-"050000007e0500000920000001800000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,",-"050000007e0500000720000001800000,Nintendo Switch Right Joy-Con,a:b1,b:b2,back:b9,leftshoulder:b4,leftstick:b10,leftx:a1~,lefty:a0,rightshoulder:b6,start:b8,x:b0,y:b3,platform:Linux,",-"05000000010000000100000003000000,Nintendo Wii Remote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",-"050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,",-"030000000d0500000308000010010000,Nostromo n45 Dual Analog,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux,",-"050000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Linux,",-"050000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,",-"03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",-"03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,",-"05000000550900001472000001000000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,",-"03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"19000000010000000100000001010000,ODROID Go 2,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux,",-"19000000010000000200000011000000,ODROID Go 2,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,y:b3,platform:Linux,",-"03000000c0160000dc27000001010000,OnyxSoft Dual JoyDivision,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:Linux,",-"05000000362800000100000002010000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,",-"05000000362800000100000003010000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,",-"05000000362800000100000004010000,OUYA Controller,a:b0,b:b3,back:b14,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,start:b16,x:b1,y:b2,platform:Linux,",-"03000000830500005020000010010000,Padix Rockfire PlayStation Bridge,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Linux,",-"03000000790000001c18000011010000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"03000000ff1100003133000010010000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"030000006f0e0000b802000001010000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006f0e0000b802000013020000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006f0e0000d702000006640000,PDP Black Camo Wired Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b13,dpup:b14,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006f0e00003101000000010000,PDP EA Sports Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006f0e00008001000011010000,PDP Faceoff Nintendo Switch Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006f0e00008501000011010000,PDP Nintendo Switch Fightpad Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"030000006f0e00002801000011010000,PDP PS3 Rock Candy Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000006f0e00008701000011010000,PDP Rock Nintendo Switch Candy Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"030000006f0e00000901000011010000,PDP Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",-"030000006f0e0000a802000023020000,PDP Xbox One Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",-"030000006f0e0000a702000023020000,PDP Xbox One Raven Black,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000004c050000da0c000011010000,PlayStation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,",-"03000000d9040000160f000000010000,PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",-"030000004c0500003713000011010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,",-"03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000d62000000140000001010000,PowerA Fusion Pro 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000c62400001a53000000010000,PowerA Mini Pro Ex,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000c62400001a58000001010000,PowerA Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000d62000000220000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,",-"03000000d62000000228000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000c62400001a54000001010000,PowerA Xbox One Mini Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000d62000000240000001010000,PowerA Xbox One Spectra Infinity,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,",-"03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000004c0500006802000010010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",-"030000004c0500006802000010810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",-"030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",-"030000004c0500006802000011810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",-"030000005f1400003102000010010000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"030000006f0e00001402000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000008f0e00000300000010010000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"050000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",-"050000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:a12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:a13,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",-"050000004c0500006802000000800000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",-"050000004c0500006802000000810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",-"05000000504c415953544154494f4e00,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",-"060000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",-"030000004c050000a00b000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"030000004c050000a00b000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",-"030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"030000004c050000c405000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",-"030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"030000004c050000cc09000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"030000004c050000cc09000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",-"03000000c01100000140000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"050000004c050000c405000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",-"050000004c050000c405000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",-"050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",-"050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",-"030000004c050000e60c000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,",-"030000004c050000e60c000011810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",-"050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,",-"050000004c050000e60c000000810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",-"03000000300f00001211000011010000,Qanba Arcade Joystick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux,",-"03000000222c00000225000011010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000222c00000025000011010000,Qanba Dragon Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"03000000300f00001210000010010000,Qanba Joystick Plus,a:b0,b:b1,back:b8,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,start:b9,x:b2,y:b3,platform:Linux,",-"03000000222c00000223000011010000,Qanba Obsidian Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000222c00000023000011010000,Qanba Obsidian Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"030000009b2800000300000001010000,Raphnet 4nes4snes,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,",-"030000009b2800004200000001010000,Raphnet Dual NES Adapter,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Linux,",-"030000009b2800003200000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,",-"030000009b2800006000000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,",-"030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000008916000000fd000024010000,Razer Onza Tournament Edition,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000321500000204000011010000,Razer Panthera PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000321500000104000011010000,Razer Panthera PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"03000000321500000810000011010000,Razer Panthera PS4 Evo Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"03000000321500000010000011010000,Razer Raiju,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"03000000321500000507000000010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"05000000321500000a10000001000000,Razer Raiju Tournament Edition,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"03000000321500000011000011010000,Razer Raion PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"030000008916000000fe000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000c6240000045d000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000321500000009000011010000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",-"050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",-"0300000032150000030a000001010000,Razer Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000790000001100000010010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Linux,",-"0300000081170000990a000001010000,Retronic Adapter,a:b0,leftx:a0,lefty:a1,platform:Linux,",-"0300000000f000000300000000010000,RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,",-"00000000526574726f53746f6e653200,RetroStone 2 Controller,a:b1,b:b0,back:b10,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,righttrigger:b9,start:b11,x:b4,y:b3,platform:Linux,",-"030000006b140000010d000011010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"030000006b140000130d000011010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"030000006f0e00001f01000000010000,Rock Candy,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006f0e00001e01000011010000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000c6240000fefa000000010000,Rock Candy Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000006f0e00004601000001010000,Rock Candy Xbox One Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000a306000023f6000011010000,Saitek Cyborg V1 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,",-"03000000a30600001005000000010000,Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux,",-"03000000a30600000701000000010000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Linux,",-"03000000a30600000cff000010010000,Saitek P2500 Force Rumble,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b0,y:b1,platform:Linux,",-"03000000a30600000c04000011010000,Saitek P2900,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux,",-"03000000a306000018f5000010010000,Saitek P3200 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,",-"03000000300f00001201000010010000,Saitek P380,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,",-"03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux,",-"03000000a30600000b04000000010000,Saitek P990 Dual Analog,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux,",-"03000000a306000020f6000011010000,Saitek PS2700 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,",-"03000000d81d00000e00000010010000,Savior,a:b0,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b9,x:b4,y:b5,platform:Linux,",-"03000000a30c00002500000011010000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Linux,",-"03000000790000001100000011010000,Sega Saturn,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Linux,",-"03000000790000002201000011010000,Sega Saturn,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,",-"03000000b40400000a01000000010000,Sega Saturn,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Linux,",-"030000001f08000001e4000010010000,SFC Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,",-"03000000632500002305000010010000,ShanWan Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"03000000f025000021c1000010010000,Shanwan Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"03000000632500007505000010010000,Shanwan PS3 PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"03000000bc2000000055000010010000,Shanwan PS3 PC ,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"03000000341a00000908000010010000,SL6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",-"050000004c050000cc09000001000000,Sony DualShock 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"03000000ff000000cb01000010010000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,",-"03000000250900000500000000010000,Sony PS2 pad with SmartJoy Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,",-"030000005e0400008e02000073050000,Speedlink Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e0400008e02000020200000,SpeedLink Xeox Pro Analog,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000d11800000094000011010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",-"03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",-"03000000de2800000112000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,",-"03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",-"03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,",-"03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",-"03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,",-"03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",-"05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",-"05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",-"03000000de2800000512000010010000,Steam Deck,a:b3,b:b4,back:b11,dpdown:b17,dpleft:b18,dpright:b19,dpup:b16,guide:b13,leftshoulder:b7,leftstick:b14,lefttrigger:a9,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b15,righttrigger:a8,rightx:a2,righty:a3,start:b12,x:b5,y:b6,platform:Linux,",-"03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"050000004e696d6275732b0000000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b10,guide:b11,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Linux,",-"03000000381000003014000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000381000003114000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"0500000011010000311400001b010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b32,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"05000000110100001914000009010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"03000000ad1b000038f0000090040000,Street Fighter IV Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000003b07000004a1000000010000,Suncom SFX Plus,a:b0,b:b2,back:b7,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Linux,",-"03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,",-"0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,",-"030000008f0e00000d31000010010000,SZMY Power 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000457500002211000010010000,SZMY Power Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"030000008f0e00001431000010010000,SZMY Power PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"03000000ba2200000701000001010000,Technology Innovation PS2 Adapter,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b2,platform:Linux,",-"030000004f04000015b3000001010000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,",-"030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,",-"030000004f04000020b3000010010000,Thrustmaster Dual Trigger,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,",-"030000004f04000023b3000000010000,Thrustmaster Dual Trigger PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"030000004f0400000ed0000011010000,Thrustmaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"03000000b50700000399000000010000,Thrustmaster Firestorm Digital 2,a:b2,b:b4,back:b11,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b0,righttrigger:b9,start:b1,x:b3,y:b5,platform:Linux,",-"030000004f04000003b3000010010000,Thrustmaster Firestorm Dual Analog 2,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b9,rightx:a2,righty:a3,x:b1,y:b3,platform:Linux,",-"030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux,",-"030000004f04000004b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,",-"030000004f04000026b3000002040000,Thrustmaster GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000c6240000025b000002020000,Thrustmaster GPX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000004f04000008d0000000010000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"030000004f04000009d0000000010000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000004f04000007d0000000010000,Thrustmaster T Mini,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",-"030000004f04000012b3000010010000,Thrustmaster Vibrating Gamepad,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,",-"03000000571d00002000000010010000,Tomee SNES Adapter,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,",-"03000000bd12000015d0000010010000,Tomee SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,",-"03000000d814000007cd000011010000,Toodles 2008 Chimp PC PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux,",-"030000005e0400008e02000070050000,Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000c01100000591000011010000,Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"03000000680a00000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux,",-"03000000780300000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux,",-"03000000e00d00000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux,",-"03000000f00600000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux,",-"030000005f140000c501000010010000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",-"03000000100800000100000010010000,Twin PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",-"03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",-"03000000790000000600000007010000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,",-"03000000790000001100000000010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux,",-"030000006f0e00000302000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",-"030000006f0e00000702000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",-"05000000ac0500003232000001000000,VR Box Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,",-"0000000058626f782033363020576900,Xbox 360 Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,",-"030000005e0400001907000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e0400008e02000010010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e0400008e02000014010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e0400009102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e040000a102000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e040000a102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e0400008e02000000010000,Xbox 360 EasySMX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e040000a102000014010000,Xbox 360 Receiver,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e0400000202000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,",-"030000006f0e00001304000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"03000000ffff0000ffff000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,",-"0000000058626f782047616d65706100,Xbox Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e0400000a0b000005040000,Xbox One Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,",-"030000005e040000120b000009050000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e040000d102000002010000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e040000ea02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e040000ea02000001030000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"050000005e040000e002000003090000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"050000005e040000fd02000003090000,Xbox One Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"050000005e040000fd02000030110000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"060000005e040000120b000007050000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"050000005e040000e302000002090000,Xbox One Elite,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"050000005e040000220b000013050000,Xbox One Elite 2 Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"060000005e040000ea0200000b050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"060000005e040000ea0200000d050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e040000120b000005050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e040000120b00000d050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"050000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"050000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"050000005e040000130b000009050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"050000005e040000130b000013050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"060000005e040000120b00000b050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"030000005e040000120b000007050000,Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",-"050000005e040000130b000011050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"050000005e040000130b000007050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"050000005e040000200b000013050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",-"03000000450c00002043000010010000,XEOX SL6556 BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",-"05000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,",-"03000000c0160000e105000001010000,XinMo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,",-"03000000120c0000100e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-"03000000120c0000101e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",-#endif // GLFW_BUILD_LINUX_MAPPINGS+#if defined(_GLFW_WIN32)+"03000000fa2d00000100000000000000,3DRUDDER,leftx:a0,lefty:a1,rightx:a5,righty:a2,platform:Windows,",+"03000000c82d00002038000000000000,8bitdo,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00000951000000000000,8BitDo Dogbone Modkit,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Windows,",+"03000000c82d000011ab000000000000,8BitDo F30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00001038000000000000,8BitDo F30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00000090000000000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00000650000000000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:a4,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows,",+"03000000c82d00005106000000000000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00000151000000000000,8BitDo M30 ModKit,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows,",+"03000000c82d00000310000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,",+"03000000c82d00002028000000000000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00008010000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,",+"03000000c82d00000451000000000000,8BitDo N30 Modkit,a:b1,b:b0,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,start:b11,platform:Windows,",+"03000000c82d00000190000000000000,8BitDo N30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00001590000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00006528000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",+"03000000022000000090000000000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",+"03000000203800000900000000000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00000360000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00002867000000000000,8BitDo S30 Modkit,a:b0,b:b1,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b8,lefttrigger:b9,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows,",+"03000000c82d00000130000000000000,8BitDo SF30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00000060000000000000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00000061000000000000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d000021ab000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",+"03000000102800000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00003028000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00000030000000000000,8BitDo SN30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00001290000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d000020ab000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00004028000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00006228000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00000351000000000000,8BitDo SN30 Modkit,a:b1,b:b0,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00000121000000000000,8BitDo SN30 Pro for Android,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"03000000c82d00000260000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00000261000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00000031000000000000,8BitDo Wireless Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,",+"03000000c82d00003032000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,",+"03000000a00500003232000000000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,",+"03000000a30c00002700000000000000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,",+"03000000a30c00002800000000000000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,",+"030000008f0e00001200000000000000,Acme GA-02,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,",+"03000000c01100000355000011010000,ACRUX USB GAME PAD,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000fa190000f0ff000000000000,Acteck AGJ-3200,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"030000006f0e00001413000000000000,Afterglow,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000341a00003608000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000006f0e00000263000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000006f0e00001101000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000006f0e00001401000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000006f0e00001402000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000006f0e00001901000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000006f0e00001a01000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000d62000001d57000000000000,Airflo PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000491900001904000000000000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows,",+"03000000710100001904000000000000,Amazon Luna Controller,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b8,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b4,rightstick:b7,rightx:a3,righty:a4,start:b6,x:b3,y:b2,platform:Windows,",+"03000000ef0500000300000000000000,AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows,",+"03000000d6200000e557000000000000,Batarang,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000c01100001352000000000000,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows,",+"030000006f0e00003201000000000000,Battlefield 4 PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000d62000002a79000000000000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"03000000bc2000006012000000000000,Betop 2126F,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000bc2000000055000000000000,Betop BFM Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"03000000bc2000006312000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000bc2000006321000000000000,BETOP CONTROLLER,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000bc2000006412000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000c01100000555000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000c01100000655000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000790000000700000000000000,Betop Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,",+"03000000808300000300000000000000,Betop Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,",+"030000006b1400000055000000000000,Bigben PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",+"030000006b1400000103000000000000,Bigben PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,",+"03000000120c0000210e000000000000,Brook Mars,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"0300000066f700000500000000000000,BrutalLegendTest,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",+"03000000d81d00000b00000000000000,BUFFALO BSGP1601 Series ,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows,",+"03000000e82000006058000000000000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000457500000401000000000000,Cobra,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000005e0400008e02000000000000,Controller (XBOX 360 For Windows),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",+"030000005e040000a102000000000000,Controller (Xbox 360 Wireless Receiver for Windows),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",+"030000005e040000ff02000000000000,Controller (Xbox One For Windows) - Wired,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",+"030000005e040000ea02000000000000,Controller (Xbox One For Windows) - Wireless,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",+"03000000260900008888000000000000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a4,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Windows,",+"03000000a306000022f6000000000000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",+"03000000451300000830000000000000,Defender Game Racer X7,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",+"030000007d0400000840000000000000,Destroyer Tiltpad,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,x:b0,y:b3,platform:Windows,",+"03000000791d00000103000000000000,Dual Box WII,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000bd12000002e0000000000000,Dual USB Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,",+"030000008f0e00000910000000000000,DualShock 2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,",+"030000006f0e00003001000000000000,EA SPORTS PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000b80500000410000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,",+"03000000b80500000610000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,",+"03000000120c0000f61c000000000000,Elite,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000008f0e00000f31000000000000,EXEQ,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,",+"03000000341a00000108000000000000,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",+"030000006f0e00008401000000000000,Faceoff Deluxe+ Audio Wired Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000006f0e00008001000000000000,Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000852100000201000000000000,FF-GP1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00008500000000000000,Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00008400000000000000,Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00008700000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00008800000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,",+"030000000d0f00002700000000000000,FIGHTING STICK V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",+"78696e70757403000000000000000000,Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Windows,",+"03000000790000002201000000000000,Game Controller for PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"0300000066f700000100000000000000,Game VIB Joystick,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows,",+"03000000260900002625000000000000,Gamecube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows,",+"03000000790000004618000000000000,GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",+"030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000280400000140000000000000,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",+"03000000ac0500003d03000000000000,GameSir,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"03000000ac0500004d04000000000000,GameSir,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"03000000ffff00000000000000000000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",+"03000000c01100000140000000000000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000009b2800003200000000000000,GC/N64 to USB v3.4,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,",+"030000009b2800006000000000000000,GC/N64 to USB v3.6,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,",+"030000008305000009a0000000000000,Genius,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",+"030000008305000031b0000000000000,Genius Maxfire Blaze 3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",+"03000000451300000010000000000000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",+"030000005c1a00003330000000000000,Genius MaxFire Grandias 12V,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,",+"03000000300f00000b01000000000000,GGE909 Recoil Pad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",+"03000000f0250000c283000000000000,Gioteck,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000f025000021c1000000000000,Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000f0250000c383000000000000,Gioteck VX2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000f0250000c483000000000000,Gioteck VX2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"030000007d0400000540000000000000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",+"03000000341a00000302000000000000,Hama Scorpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00004900000000000000,Hatsune Miku Sho Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000001008000001e1000000000000,Havit HV-G60,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows,",+"03000000d81400000862000000000000,HitBox Edition Cthulhu+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,",+"03000000632500002605000000000000,HJD-X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"030000000d0f00002d00000000000000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00005f00000000000000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00005e00000000000000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00004000000000000000,Hori Fighting Stick Mini 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00005400000000000000,Hori Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00000900000000000000,Hori Pad 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00004d00000000000000,Hori Pad A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00009200000000000000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00001600000000007803,HORI Real Arcade Pro EX-SE (Xbox 360),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Windows,",+"030000000d0f00009c00000000000000,Hori TAC Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f0000c100000000000000,Horipad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00006e00000000000000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00006600000000000000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00005500000000000000,Horipad 4 FPS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f0000ee00000000000000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"03000000250900000017000000000000,HRAP2 on PS/SS/N64 Joypad to USB BOX,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows,",+"030000008f0e00001330000000000000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Windows,",+"03000000d81d00000f00000000000000,iBUFFALO BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000d81d00001000000000000000,iBUFFALO BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000830500006020000000000000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Windows,",+"03000000b50700001403000000000000,Impact Black,a:b2,b:b3,back:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",+"030000006f0e00002401000000000000,INJUSTICE FightStick PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",+"03000000ac0500002c02000000000000,IPEGA,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"03000000491900000204000000000000,Ipega PG-9023,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"03000000491900000304000000000000,Ipega PG-9087 - Bluetooth Gamepad,+righty:+a5,-righty:-a4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,start:b11,x:b3,y:b4,platform:Windows,",+"030000006e0500000a20000000000000,JC-DUX60 ELECOM MMO Gamepad,a:b2,b:b3,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b14,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b15,righttrigger:b13,rightx:a3,righty:a4,start:b20,x:b0,y:b1,platform:Windows,",+"030000006e0500000520000000000000,JC-P301U,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,",+"030000006e0500000320000000000000,JC-U3613M (DInput),a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,",+"030000006e0500000720000000000000,JC-W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,",+"030000007e0500000620000000000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Windows,",+"030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Windows,",+"030000007e0500000720000000000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,",+"030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,",+"03000000bd12000003c0000010010000,Joypad Alpha Shock,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000bd12000003c0000000000000,JY-P70UR,a:b1,b:b0,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b11,righttrigger:b9,rightx:a3,righty:a2,start:b4,x:b3,y:b2,platform:Windows,",+"03000000242f00002d00000000000000,JYS Wireless Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000242f00008a00000000000000,JYS Wireless Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,",+"03000000790000000200000000000000,King PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,",+"030000006d040000d1ca000000000000,Logitech ChillStream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000006d040000d2ca000000000000,Logitech Cordless Precision,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000006d04000011c2000000000000,Logitech Cordless Wingman,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b2,righttrigger:b7,rightx:a3,righty:a4,x:b4,platform:Windows,",+"030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000006d04000018c2000000000000,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000006d04000019c2000000000000,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000006d0400001ac2000000000000,Logitech Precision Gamepad,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",+"030000006d0400000ac2000000000000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows,",+"03000000380700006652000000000000,Mad Catz C.T.R.L.R,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",+"03000000380700005032000000000000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000380700005082000000000000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"03000000380700008433000000000000,Mad Catz FightStick TE S+ (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000380700008483000000000000,Mad Catz FightStick TE S+ (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"03000000380700008134000000000000,Mad Catz FightStick TE2+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000380700008184000000000000,Mad Catz FightStick TE2+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"03000000380700006252000000000000,Mad Catz Micro C.T.R.L.R,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",+"03000000380700008034000000000000,Mad Catz TE2 PS3 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000380700008084000000000000,Mad Catz TE2 PS4 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"03000000380700008532000000000000,Madcatz Arcade Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000380700003888000000000000,Madcatz Arcade Fightstick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000380700001888000000000000,MadCatz SFIV FightStick PS3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",+"03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000002a0600001024000000000000,Matricom,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,",+"030000009f000000adbb000000000000,MaxJoypad Virtual Controller,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",+"03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows,",+"03000000790000004418000000000000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",+"03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,back:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b0,leftshoulder:b4,leftstick:b0,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",+"03000000242f00007300000000000000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,",+"0300000079000000d218000000000000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000d620000010a7000000000000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000008f0e00001030000000000000,Mayflash USB Adapter for original Sega Saturn controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,platform:Windows,",+"0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,",+"03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000790000002418000000000000,Mega Drive,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b2,start:b9,x:b3,y:b4,platform:Windows,",+"03000000380700006382000000000000,MLG GamePad PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000c62400002a89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"03000000c62400002b89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"03000000c62400001a89000000000000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"03000000c62400001b89000000000000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"03000000efbe0000edfe000000000000,Monect Virtual Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows,",+"03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",+"030000006b140000010c000000000000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",+"03000000921200004b46000000000000,NES 2-port Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Windows,",+"03000000790000004518000000000000,NEXILUX GAMECUBE Controller Adapter,platform:Windows,a:b1,b:b0,x:b2,y:b3,start:b9,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,",+"030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Windows,",+"03000000152000000182000000000000,NGDS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows,",+"03000000bd12000015d0000000000000,Nintendo Retrolink USB Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,",+"030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",+"030000000d0500000308000000000000,Nostromo N45,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Windows,",+"03000000550900001472000000000000,NVIDIA Controller v01.04,a:b11,b:b10,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b5,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b4,righttrigger:a5,rightx:a3,righty:a6,start:b3,x:b9,y:b8,platform:Windows,",+"030000004b120000014d000000000000,NYKO AIRFLO,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,rightshoulder:b5,rightstick:a2,righttrigger:b7,start:b9,x:b2,y:b3,platform:Windows,",+"03000000d620000013a7000000000000,NSW wired controller,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",+"03000000782300000a10000000000000,Onlive Wireless Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,platform:Windows,",+"03000000d62000006d57000000000000,OPP PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000006b14000001a1000000000000,Orange Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,",+"03000000362800000100000000000000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows,",+"03000000120c0000f60e000000000000,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,",+"030000006f0e00000901000000000000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",+"030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",+"030000004c050000da0c000000000000,PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,",+"030000004c0500003713000000000000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",+"03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000d62000009557000000000000,Pro Elite PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000d62000009f31000000000000,Pro Ex mini PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000d6200000c757000000000000,Pro Ex mini PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000632500002306000000000000,PS Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,",+"03000000e30500009605000000000000,PS to USB convert cable,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",+"03000000100800000100000000000000,PS1 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",+"030000008f0e00007530000000000000,PS1 Controller,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b1,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000100800000300000000000000,PS2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",+"03000000250900008888000000000000,PS2 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",+"03000000666600006706000000000000,PS2 Controller,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Windows,",+"030000006b1400000303000000000000,PS2 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",+"030000009d0d00001330000000000000,PS2 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",+"03000000250900000500000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows,",+"030000004c0500006802000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b10,lefttrigger:a3~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:a4~,rightx:a2,righty:a5,start:b8,x:b3,y:b0,platform:Windows,",+"03000000632500007505000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000888800000803000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,",+"030000008f0e00001431000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000003807000056a8000000000000,PS3 RF pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000100000008200000000000000,PS360+ v1.66,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:h0.4,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",+"030000004c050000a00b000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000004c050000cc09000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000004c050000e60c000000000000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"03000000ff000000cb01000000000000,PSP,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,",+"03000000300f00000011000000000000,QanBa Arcade JoyStick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows,",+"03000000300f00001611000000000000,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,",+"03000000222c00000020000000000000,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows,",+"03000000300f00001210000000000000,QanBa Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,",+"03000000341a00000104000000000000,QanBa Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,platform:Windows,",+"03000000222c00000223000000000000,Qanba Obsidian Arcade Joystick PS3 Mode,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000222c00000023000000000000,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",+"03000000321500000204000000000000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000321500000104000000000000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"03000000321500000507000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"03000000321500000707000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"03000000321500000011000000000000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"03000000321500000009000000000000,Razer Serval,+lefty:+a2,-lefty:-a1,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,leftx:a0,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",+"030000000d0f00001100000000000000,REAL ARCADE PRO.3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00006a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00006b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00008a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00008b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00007000000000000000,REAL ARCADE PRO.4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00002200000000000000,REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00005b00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000000d0f00005c00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000790000001100000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,",+"03000000bd12000013d0000000000000,Retrolink USB SEGA Saturn Classic,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,lefttrigger:b6,rightshoulder:b2,righttrigger:b7,start:b8,x:b3,y:b4,platform:Windows,",+"0300000000f000000300000000000000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,",+"0300000000f00000f100000000000000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,",+"030000006b140000010d000000000000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000006b140000020d000000000000,Revolution Pro Controller 2(1/2),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000006b140000130d000000000000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000006f0e00001e01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000006f0e00002801000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000006f0e00002f01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000004f04000003d0000000000000,run'n'drive,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"03000000a30600001af5000000000000,Saitek Cyborg,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",+"03000000a306000023f6000000000000,Saitek Cyborg V.1 Game pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",+"03000000300f00001201000000000000,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",+"03000000a30600000701000000000000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Windows,",+"03000000a30600000cff000000000000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b0,y:b1,platform:Windows,",+"03000000a30600000c04000000000000,Saitek P2900,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",+"03000000300f00001001000000000000,Saitek P480 Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",+"03000000a30600000b04000000000000,Saitek P990,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,",+"03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Windows,",+"03000000a30600002106000000000000,Saitek PS1000,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",+"03000000a306000020f6000000000000,Saitek PS2700,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,",+"03000000300f00001101000000000000,Saitek Rumble Pad,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",+"03000000730700000401000000000000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows,",+"0300000000050000289b000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,",+"030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,",+"03000000a30c00002500000000000000,Sega Genesis Mini 3B controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Windows,",+"03000000a30c00002400000000000000,Sega Mega Drive Mini 6B controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,",+"03000000341a00000208000000000000,SL-6555-SBK,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows,",+"03000000341a00000908000000000000,SL-6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",+"030000008f0e00000800000000000000,SpeedLink Strike FX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000c01100000591000000000000,Speedlink Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000d11800000094000000000000,Stadia Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b11,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,",+"03000000110100001914000000000000,SteelSeries,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"03000000381000001214000000000000,SteelSeries Free,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,",+"03000000110100003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"03000000381000001814000000000000,SteelSeries Stratus XL,a:b0,b:b1,back:b18,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b19,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b2,y:b3,platform:Windows,",+"03000000790000001c18000000000000,STK-7024X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"03000000ff1100003133000000000000,SVEN X-PAD,a:b2,b:b3,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a4,start:b5,x:b0,y:b1,platform:Windows,",+"03000000d620000011a7000000000000,Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000457500002211000000000000,SZMY-POWER PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000004f04000007d0000000000000,T Mini Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000004f0400000ab1000000000000,T.16000M,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b10,x:b2,y:b3,platform:Windows,",+"03000000fa1900000706000000000000,Team 5,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000b50700001203000000000000,Techmobility X6-38V,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,",+"030000004f04000015b3000000000000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,",+"030000004f04000023b3000000000000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000004f0400000ed0000000000000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows,",+"030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,",+"03000000666600000488000000000000,TigerGame PS/PS2 Game Controller Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,",+"03000000d62000006000000000000000,Tournament PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"030000005f140000c501000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000b80500000210000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"030000004f04000087b6000000000000,TWCS Throttle,dpdown:b8,dpleft:b9,dpright:b7,dpup:b6,leftstick:b5,lefttrigger:-a5,leftx:a0,lefty:a1,righttrigger:+a5,platform:Windows,",+"03000000d90400000200000000000000,TwinShock PS2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",+"030000006e0500001320000000000000,U4113,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000101c0000171c000000000000,uRage Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000300f00000701000000000000,USB 4-Axis 12-Button Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",+"03000000341a00002308000000000000,USB gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",+"030000005509000000b4000000000000,USB gamepad,a:b10,b:b11,back:b5,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,guide:b14,leftshoulder:b8,leftstick:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:a5,rightx:a2,righty:a3,start:b4,x:b12,y:b13,platform:Windows,",+"030000006b1400000203000000000000,USB gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",+"03000000790000000a00000000000000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,",+"03000000f0250000c183000000000000,USB gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000ff1100004133000000000000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,",+"03000000632500002305000000000000,USB Vibration Joystick (BM),a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000790000001a18000000000000,Venom,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",+"03000000790000001b18000000000000,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",+"030000006f0e00000302000000000000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",+"030000006f0e00000702000000000000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",+"0300000034120000adbe000000000000,vJoy Device,a:b0,b:b1,back:b15,dpdown:b6,dpleft:b7,dpright:b8,dpup:b5,guide:b16,leftshoulder:b9,leftstick:b13,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b14,righttrigger:b12,rightx:a3,righty:a4,start:b4,x:b2,y:b3,platform:Windows,",+"030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",+"030000005e040000130b000000000000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",+"03000000341a00000608000000000000,Xeox,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",+"03000000450c00002043000000000000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",+"03000000ac0500005b05000000000000,Xiaoji Gamesir-G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,",+"03000000172700004431000000000000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,",+"03000000786901006e70000000000000,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,",+"03000000790000004f18000000000000,ZD-T Android,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,",+"03000000120c0000101e000000000000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",+"78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",+"78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",+"78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",+"78696e70757404000000000000000000,XInput Flight Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",+"78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",+"78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",+"78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",+#endif // _GLFW_WIN32++#if defined(_GLFW_COCOA)+"030000008f0e00000300000009010000,2In1 USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,",+"03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",+"03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",+"03000000c82d00000650000001000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Mac OS X,",+"03000000c82d00005106000000010000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,start:b11,x:b4,y:b3,platform:Mac OS X,",+"03000000c82d00001590000001000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",+"03000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",+"030000003512000012ab000001000000,8BitDo NES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,",+"03000000022000000090000001000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",+"03000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",+"03000000c82d00000190000001000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",+"03000000102800000900000000000000,8Bitdo SFC30 GamePad Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,",+"03000000c82d00001290000001000000,8BitDo SN30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,",+"03000000c82d00004028000000010000,8Bitdo SN30 GamePad,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0,platform:Mac OS X,",+"03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",+"03000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Mac OS X,",+"03000000c82d00000260000001000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",+"03000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,",+"03000000c82d00000031000001000000,8BitDo Wireless Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",+"03000000c82d00001890000001000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,",+"03000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a31,start:b11,x:b4,y:b3,platform:Mac OS X,",+"03000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,",+"03000000a00500003232000009010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,",+"03000000a30c00002700000003030000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",+"03000000a30c00002800000003030000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",+"03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,",+"03000000ef0500000300000000020000,AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Mac OS X,",+"03000000491900001904000001010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Mac OS X,",+"03000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,",+"03000000c62400001a89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,",+"03000000c62400001b89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",+"03000000d62000002a79000000010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000120c0000200e000000010000,Brook Mars,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000120c0000210e000000010000,Brook Mars,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,",+"03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000790000004618000000010000,GameCube Controller Adapter,a:b4,b:b0,dpdown:b56,dpleft:b60,dpright:b52,dpup:b48,lefttrigger:a12,leftx:a0,lefty:a4,rightshoulder:b28,righttrigger:a16,rightx:a20,righty:a8,start:b36,x:b8,y:b12,platform:Mac OS X,",+"03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",+"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,",+"03000000c01100000140000000010000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000006f0e00000102000000000000,GameStop Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",+"030000007d0400000540000001010000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000280400000140000000020000,Gravis Gamepad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000008f0e00000300000007010000,GreenAsia Inc. USB Joystick,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Mac OS X,",+"030000000d0f00002d00000000100000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000000d0f00005f00000000010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000000d0f00005e00000000010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000000d0f00005f00000000000000,HORI Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000000d0f00005e00000000000000,HORI Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000000d0f00004d00000000000000,HORI Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000000d0f00009200000000010000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000000d0f00006e00000000010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000000d0f00006600000000010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000000d0f00006600000000000000,HORIPAD FPS PLUS 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000000d0f0000ee00000000010000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000008f0e00001330000011010000,HuiJia SNES Controller,a:b4,b:b2,back:b16,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b12,rightshoulder:b14,start:b18,x:b6,y:b0,platform:Mac OS X,",+"03000000830500006020000000010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,",+"03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,",+"030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Mac OS X,",+"030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Mac OS X,",+"03000000242f00002d00000007010000,JYS Wireless Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,",+"030000006d04000016c2000000020000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000006d04000016c2000000030000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000006d04000016c2000014040000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000006d04000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000006d04000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000006d04000019c2000005030000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000006d0400001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",+"030000006d04000018c2000000010000,Logitech RumblePad 2 USB,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3~,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000006d04000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000380700005032000000010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000380700005082000000010000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000380700008433000000010000,Mad Catz FightStick TE S+ (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000380700008483000000010000,Mad Catz FightStick TE S+ (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000790000000600000007010000,Marvo GT-004,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Mac OS X,",+"03000000790000004418000000010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000242f00007300000000020000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Mac OS X,",+"0300000079000000d218000026010000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,",+"03000000d620000010a7000003010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X,",+"03000000790000000018000000010000,Mayflash Wii U Pro Controller Adapter,a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,",+"03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,",+"03000000d8140000cecf000000000000,MC Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000005e0400002700000001010000,Microsoft SideWinder Plug & Play Game Pad,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,leftx:a0,lefty:a1,righttrigger:b5,x:b2,y:b3,platform:Mac OS X,",+"03000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,",+"03000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",+"03000000c62400002b89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",+"03000000632500007505000000020000,NEOGEO mini PAD Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b2,y:b3,platform:Mac OS X,",+"03000000921200004b46000003020000,NES 2-port Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Mac OS X,",+"030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Mac OS X,",+"03000000d620000011a7000000020000,Nintendo Switch Core (Plus) Wired Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000d620000011a7000010050000,Nintendo Switch PowerA Wired Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,",+"030000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,",+"03000000550900001472000025050000,NVIDIA Controller v01.04,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Mac OS X,",+"030000006f0e00000901000002010000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,",+"030000004c050000da0c000000010000,Playstation Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",+"030000004c0500003713000000010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000d62000006dca000000010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000100800000300000006010000,PS2 Adapter,a:b2,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,",+"030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,",+"030000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,",+"030000004c050000a00b000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",+"03000000321500000204000000010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000321500000104000000010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000321500000010000000010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000321500000507000001010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",+"03000000321500000011000000010000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000321500000009000000020000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,",+"030000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,",+"0300000032150000030a000000000000,Razer Wildcat,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",+"03000000790000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",+"03000000790000001100000006010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",+"030000006b140000010d000000010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000006b140000130d000000010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000c6240000fefa000000000000,Rock Candy Gamepad for PS3,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",+"03000000730700000401000000010000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Mac OS X,",+"03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X,",+"03000000b40400000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X,",+"030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,",+"0300000000f00000f100000000000000,SNES RetroPort,a:b2,b:b3,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,rightshoulder:b7,start:b6,x:b0,y:b1,platform:Mac OS X,",+"030000004c050000e60c000000010000,Sony DualSense,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000d11800000094000000010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,",+"030000005e0400008e02000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",+"03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X,",+"03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,",+"03000000381000002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,",+"050000004e696d6275732b0000000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,",+"03000000110100001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,",+"03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,",+"03000000457500002211000000010000,SZMY-POWER PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X,",+"030000004f0400000ed0000000020000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X,",+"03000000bd12000015d0000000000000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",+"03000000bd12000015d0000000010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,",+"03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X,",+"030000006f0e00000302000025040000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",+"030000006f0e00000702000003060000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000791d00000103000009010000,Wii Classic Controller,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,",+"050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X,",+"050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X,",+"030000005e0400008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",+"030000006f0e00000104000000000000,Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",+"03000000c6240000045d000000000000,Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",+"030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",+"030000005e040000050b000003090000,Xbox Elite Wireless Controller Series 2,a:b0,b:b1,back:b31,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b53,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",+"03000000c62400003a54000000000000,Xbox One PowerA Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",+"030000005e040000d102000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",+"030000005e040000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",+"030000005e040000e302000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",+"030000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",+"030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",+"030000005e040000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,",+"030000005e040000e002000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,",+"030000005e040000ea02000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",+"030000005e040000fd02000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,",+"03000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X,",+"03000000120c0000100e000000010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+"03000000120c0000101e000000010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,",+#endif // _GLFW_COCOA++#if defined(GLFW_BUILD_LINUX_JOYSTICK)+"03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",+"05000000c82d00001038000000010000,8Bitdo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",+"05000000c82d00005106000000010000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Linux,",+"03000000c82d00001590000011010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",+"05000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",+"03000000c82d00000310000011010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux,",+"05000000c82d00008010000000010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux,",+"03000000022000000090000011010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",+"05000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",+"05000000c82d00002038000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",+"03000000c82d00000190000011010000,8Bitdo NES30 Pro 8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",+"05000000c82d00000060000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",+"05000000c82d00000061000000010000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",+"03000000c82d000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,",+"030000003512000012ab000010010000,8Bitdo SFC30 GamePad,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux,",+"05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,",+"05000000c82d00003028000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,",+"03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux,",+"03000000c82d00000160000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",+"03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux,",+"03000000c82d00001290000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux,",+"05000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",+"05000000c82d00006228000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",+"03000000c82d00000260000011010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",+"05000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",+"05000000202800000900000000010000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,",+"03000000c82d00000031000011010000,8BitDo Wireless Adapter (DInput),a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"030000005e0400008e02000020010000,8BitDo Wireless Adapter (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,",+"05000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,",+"050000005e040000e002000030110000,8BitDo Zero 2 (XInput),a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,",+"05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,",+"05000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,",+"03000000c01100000355000011010000,ACRUX USB GAME PAD,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000006f0e00001302000000010000,Afterglow,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000006f0e00003901000020060000,Afterglow Controller for Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000006f0e00003901000000430000,Afterglow Prismatic Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000006f0e00003901000013020000,Afterglow Prismatic Wired Controller 048-007-NA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",+"030000007c1800000006000010010000,Alienware Dual Compatible Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Linux,",+"05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"03000000491900001904000011010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Linux,",+"05000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,",+"03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",+"03000000a30c00002700000011010000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,",+"03000000a30c00002800000011010000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,",+"05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,",+"05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,",+"03000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,platform:Linux,",+"05000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,platform:Linux,",+"03000000503200000210000000000000,Atari Game Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,",+"05000000503200000210000000000000,Atari Game Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,",+"03000000120c00000500000010010000,AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux,",+"03000000ef0500000300000000010000,AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux,",+"03000000c62400001b89000011010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"03000000d62000002a79000011010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"03000000c21100000791000011010000,Be1 GC101 Controller 1.03 mode,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"03000000c31100000791000011010000,Be1 GC101 GAMEPAD 1.03 mode,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"030000005e0400008e02000003030000,Be1 GC101 Xbox 360 Controller mode,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"05000000bc2000000055000001000000,BETOP AX1 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux,",+"03000000120c0000200e000011010000,Brook Mars,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"03000000120c0000210e000011010000,Brook Mars,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"03000000120c0000f70e000011010000,Brook Universal Fighting Board,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",+"03000000ffff0000ffff000000010000,Chinese-made Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,",+"03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux,",+"03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux,",+"03000000a306000022f6000011010000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,",+"03000000b40400000a01000000010000,CYPRESS USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,",+"03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,",+"030000004f04000004b3000010010000,Dual Power 2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,",+"030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,",+"03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",+"030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000008f0e00000800000010010000,Gasia Co. Ltd PS(R) Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"030000006f0e00001304000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000451300000010000010010000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",+"03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"0300000079000000d418000000010000,GPD Win 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000007d0400000540000000010000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",+"03000000280400000140000000010000,Gravis GamePad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",+"030000008f0e00000610000000010000,GreenAsia Electronics 4Axes 12Keys GamePad ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux,",+"030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,",+"0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",+"03000000f0250000c383000010010000,GT VX2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"06000000adde0000efbe000002010000,Hidromancer Game Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux,",+"03000000c9110000f055000011010000,HJC Game GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",+"03000000632500002605000010010000,HJD-X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"030000000d0f00000d00000000010000,hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftx:b4,lefty:b5,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux,",+"030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",+"030000000d0f0000c100000011010000,HORI CO. LTD. HORIPAD S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000000d0f00006a00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"030000000d0f00006b00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",+"030000000d0f00008500000010010000,HORI Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000000d0f00008600000002010000,Hori Fighting Commander,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",+"030000000d0f00005f00000011010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000000d0f00005e00000011010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",+"030000000d0f0000aa00000011010000,HORI Real Arcade Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"030000000d0f0000d800000072056800,HORI Real Arcade Pro S,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,",+"030000000d0f00001600000000010000,Hori Real Arcade Pro.EX-SE (Xbox 360),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,",+"030000000d0f00006e00000011010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000000d0f00006600000011010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"030000000d0f0000ee00000011010000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"030000000d0f00006700000001010000,HORIPAD ONE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000008f0e00001330000010010000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Linux,",+"03000000242e00008816000001010000,Hyperkin X91,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,",+"050000006964726f69643a636f6e0000,idroid:con,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"03000000b50700001503000010010000,impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,",+"03000000d80400008200000003000000,IMS PCU#0 Gamepad Interface,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux,",+"03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux,",+"0500000049190000020400001b010000,Ipega PG-9069 - Bluetooth Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b161,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"03000000632500007505000011010000,Ipega PG-9099 - Bluetooth Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,",+"03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,",+"03000000300f00000b01000010010000,Jess Tech GGE909 PC Recoil Pad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",+"03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",+"030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux,",+"050000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux,",+"030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux,",+"050000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux,",+"03000000bd12000003c0000010010000,Joypad Alpha Shock,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"03000000242f00002d00000011010000,JYS Wireless Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"03000000242f00008a00000011010000,JYS Wireless Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux,",+"030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000006d040000d1ca000000000000,Logitech ChillStream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000006d0400001ec2000019200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000006d0400000ac2000010010000,Logitech Inc. WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux,",+"030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux,",+"050000004d4f435554452d3035305800,M54-PC,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"05000000380700006652000025010000,Mad Catz C.T.R.L.R ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"03000000380700005032000011010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"03000000380700005082000011010000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux,",+"03000000380700008034000011010000,Mad Catz fightstick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"03000000380700008084000011010000,Mad Catz fightstick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"03000000380700008433000011010000,Mad Catz FightStick TE S+ (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"03000000380700008483000011010000,Mad Catz FightStick TE S+ (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000380700003847000090040000,Mad Catz Wired Xbox 360 Controller (SFIV),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",+"03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000380700001888000010010000,MadCatz PC USB Wired Stick 8818,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"03000000380700003888000010010000,MadCatz PC USB Wired Stick 8838,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"03000000242f0000f700000001010000,Magic-S Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000120c00000500000000010000,Manta Dualshock 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,",+"03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,",+"03000000790000004318000010010000,Mayflash GameCube Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,",+"03000000242f00007300000011010000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux,",+"0300000079000000d218000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"03000000d620000010a7000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"0300000025090000e803000001010000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,",+"03000000780000000600000010010000,Microntek USB Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,",+"030000005e0400000e00000000010000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,",+"030000005e0400008e02000004010000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000005e0400008e02000062230000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"050000005e040000050b000003090000,Microsoft X-Box One Elite 2 pad,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"030000005e040000e302000003020000,Microsoft X-Box One Elite pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000005e040000d102000001010000,Microsoft X-Box One pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000005e040000dd02000003020000,Microsoft X-Box One pad (Firmware 2015),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000005e040000d102000003020000,Microsoft X-Box One pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,",+"030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,",+"030000005e040000000b000008040000,Microsoft Xbox One Elite 2 pad - Wired,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000005e040000ea02000008040000,Microsoft Xbox One S pad - Wired,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000c62400001a53000000010000,Mini PE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,",+"05000000d6200000e589000001000000,Moga 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,",+"05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,",+"05000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,",+"03000000c62400002b89000011010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"05000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"05000000c62400001a89000000010000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"03000000250900006688000000010000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,",+"030000006b140000010c000010010000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",+"030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"03000000790000004518000010010000,NEXILUX GAMECUBE Controller Adapter,a:b1,b:b0,x:b2,y:b3,start:b9,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,platform:Linux,",+"030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Linux,",+"060000007e0500003713000000000000,Nintendo 3DS,a:b0,b:b1,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,",+"060000007e0500000820000000000000,Nintendo Combined Joy-Cons (joycond),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,",+"030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux,",+"03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b2,y:b3,platform:Linux,",+"050000007e0500000620000001800000,Nintendo Switch Left Joy-Con,a:b9,b:b8,back:b5,leftshoulder:b2,leftstick:b6,leftx:a1,lefty:a0~,rightshoulder:b4,start:b0,x:b7,y:b10,platform:Linux,",+"030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,",+"050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",+"050000007e0500000920000001800000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,",+"050000007e0500000720000001800000,Nintendo Switch Right Joy-Con,a:b1,b:b2,back:b9,leftshoulder:b4,leftstick:b10,leftx:a1~,lefty:a0~,rightshoulder:b6,start:b8,x:b0,y:b3,platform:Linux,",+"050000007e0500001720000001000000,Nintendo Switch SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux,",+"050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,",+"05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",+"030000000d0500000308000010010000,Nostromo n45 Dual Analog Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux,",+"03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",+"03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,",+"05000000550900001472000001000000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,",+"03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"19000000010000000100000001010000,odroidgo2_joypad,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux,",+"19000000010000000200000011000000,odroidgo2_joypad_v11,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,y:b3,platform:Linux,",+"030000005e0400000202000000010000,Old Xbox pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,",+"03000000c0160000dc27000001010000,OnyxSoft Dual JoyDivision,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:Linux,",+"05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,",+"05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,",+"03000000830500005020000010010000,Padix Co. Ltd. Rockfire PSX/USB Bridge,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Linux,",+"03000000790000001c18000011010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"030000006f0e0000b802000001010000,PDP AFTERGLOW Wired Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000006f0e0000b802000013020000,PDP AFTERGLOW Wired Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000006f0e00008001000011010000,PDP CO. LTD. Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000006f0e00003101000000010000,PDP EA Sports Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000006f0e00008701000011010000,PDP Rock Candy Wired Controller for Nintendo Switch,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"030000006f0e00000901000011010000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",+"030000006f0e0000a802000023020000,PDP Wired Controller for Xbox One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",+"030000006f0e00008501000011010000,PDP Wired Fight Pad Pro for Nintendo Switch,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"0500000049190000030400001b010000,PG-9099,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"05000000491900000204000000000000,PG-9118,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"030000004c050000da0c000011010000,Playstation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,",+"030000004c0500003713000011010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,",+"03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"03000000d62000000228000001010000,PowerA Wired Controller for Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000c62400001a58000001010000,PowerA Xbox One Cabled,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000c62400001a54000001010000,PowerA Xbox One Mini Wired Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,",+"03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000004c0500006802000010010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",+"030000004c0500006802000010810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",+"030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",+"030000004c0500006802000011810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",+"030000006f0e00001402000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000008f0e00000300000010010000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"050000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",+"050000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:a12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:a13,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",+"050000004c0500006802000000800000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",+"050000004c0500006802000000810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",+"05000000504c415953544154494f4e00,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",+"060000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,",+"030000004c050000a00b000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"030000004c050000a00b000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",+"030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"030000004c050000c405000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",+"030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"030000004c050000cc09000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"030000004c050000cc09000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",+"03000000c01100000140000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"050000004c050000c405000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",+"050000004c050000c405000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",+"050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",+"050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",+"030000004c050000e60c000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"03000000ff000000cb01000010010000,PSP,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,",+"03000000300f00001211000011010000,QanBa Arcade JoyStick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux,",+"030000009b2800004200000001010000,Raphnet Technologies Dual NES to USB v2.0,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Linux,",+"030000009b2800003200000001010000,Raphnet Technologies GC/N64 to USB v3.4,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,",+"030000009b2800006000000001010000,Raphnet Technologies GC/N64 to USB v3.6,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,",+"030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,",+"030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000008916000000fd000024010000,Razer Onza Tournament Edition,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000321500000204000011010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"03000000321500000104000011010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"03000000321500000810000011010000,Razer Panthera Evo Arcade Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"03000000321500000010000011010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"03000000321500000507000000010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"03000000321500000011000011010000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"030000008916000000fe000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000c6240000045d000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000321500000009000011010000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",+"050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",+"0300000032150000030a000001010000,Razer Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000790000001100000010010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,",+"0300000081170000990a000001010000,Retronic Adapter,a:b0,leftx:a0,lefty:a1,platform:Linux,",+"0300000000f000000300000000010000,RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,",+"030000006b140000010d000011010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"030000006b140000130d000011010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"030000006f0e00001f01000000010000,Rock Candy,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000006f0e00001e01000011010000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000006f0e00004601000001010000,Rock Candy Xbox One Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,",+"03000000a30600001005000000010000,Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux,",+"03000000a30600000701000000010000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Linux,",+"03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b0,y:b1,platform:Linux,",+"03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux,",+"03000000300f00001201000010010000,Saitek P380,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,",+"03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux,",+"03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux,",+"03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,",+"03000000a306000020f6000011010000,Saitek PS2700 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,",+"03000000d81d00000e00000010010000,Savior,a:b0,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b9,x:b4,y:b5,platform:Linux,",+"03000000f025000021c1000010010000,ShanWan Gioteck PS3 Wired Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"03000000632500007505000010010000,SHANWAN PS3/PC Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"03000000bc2000000055000010010000,ShanWan PS3/PC Wired GamePad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"030000005f140000c501000010010000,SHANWAN Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"03000000632500002305000010010000,ShanWan USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"03000000341a00000908000010010000,SL-6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",+"030000004c050000e60c000011810000,Sony DualSense,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",+"050000004c050000e60c000000810000,Sony DualSense ,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,",+"03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,",+"030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000d11800000094000011010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",+"03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",+"03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",+"03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,",+"03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",+"03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,",+"03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",+"05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",+"05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,",+"03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000381000003014000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000381000003114000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"0500000011010000311400001b010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b32,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"05000000110100001914000009010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"03000000ad1b000038f0000090040000,Street Fighter IV FightStick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000003b07000004a1000000010000,Suncom SFX Plus for USB,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Linux,",+"03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,",+"0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,",+"03000000457500002211000010010000,SZMY-POWER CO. LTD. GAMEPAD,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"030000008f0e00000d31000010010000,SZMY-POWER CO. LTD. GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000008f0e00001431000010010000,SZMY-POWER CO. LTD. PS3 gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,",+"030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,",+"030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"030000004f0400000ed0000011010000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"03000000b50700000399000000010000,Thrustmaster Firestorm Digital 2,a:b2,b:b4,back:b11,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b0,righttrigger:b9,start:b1,x:b3,y:b5,platform:Linux,",+"030000004f04000003b3000010010000,Thrustmaster Firestorm Dual Analog 2,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b9,rightx:a2,righty:a3,x:b1,y:b3,platform:Linux,",+"030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux,",+"030000004f04000026b3000002040000,Thrustmaster Gamepad GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000c6240000025b000002020000,Thrustmaster GPX Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000004f04000007d0000000010000,Thrustmaster T Mini Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,",+"030000004f04000012b3000010010000,Thrustmaster vibrating gamepad,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,",+"03000000bd12000015d0000010010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,",+"03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux,",+"030000005e0400008e02000070050000,Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000c01100000591000011010000,Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",+"03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,",+"03000000790000000600000007010000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,",+"03000000790000001100000000010000,USB Gamepad1,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux,",+"030000006f0e00000302000011010000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",+"030000006f0e00000702000011010000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,",+"05000000ac0500003232000001000000,VR-BOX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,",+"03000000791d00000103000010010000,Wii Classic Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"050000000d0f0000f600000001000000,Wireless HORIPAD Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",+"030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000005e040000a102000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000005e040000a102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,",+"030000005e040000a102000014010000,Xbox 360 Wireless Receiver (XBOX),a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,",+"030000005e040000d102000002010000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"050000005e040000fd02000030110000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"030000005e040000ea02000000000000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"030000005e040000ea02000001030000,Xbox One Wireless Controller (Model 1708),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"050000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"050000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,",+"030000005e040000120b000005050000,XBox Series pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"030000005e0400008e02000000010000,xbox360 Wireless EasySMX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,",+"03000000450c00002043000010010000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,",+"03000000ac0500005b05000010010000,Xiaoji Gamesir-G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,",+"05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,",+"03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,",+"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+"03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",+#endif // GLFW_BUILD_LINUX_JOYSTICK };
raylib/src/external/glfw/src/monitor.c view
@@ -24,8 +24,6 @@ // distribution. // //========================================================================-// Please use C89 style variable declarations in this file because VS 2010-//======================================================================== #include "internal.h" @@ -452,7 +450,9 @@ _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _glfw.platform.getVideoMode(monitor, &monitor->currentMode);+ if (!_glfw.platform.getVideoMode(monitor, &monitor->currentMode))+ return NULL;+ return &monitor->currentMode; } @@ -489,7 +489,7 @@ // Apply gamma curve value = powf(value, 1.f / gamma) * 65535.f + 0.5f; // Clamp to value range- value = _glfw_fminf(value, 65535.f);+ value = fminf(value, 65535.f); values[i] = (unsigned short) value; }
raylib/src/external/glfw/src/nsgl_context.m view
@@ -23,11 +23,11 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" +#if defined(_GLFW_COCOA)+ #include <unistd.h> #include <math.h> @@ -81,12 +81,11 @@ @autoreleasepool { _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);- if (window)- {- [window->context.nsgl.object setValues:&interval- forParameter:NSOpenGLContextParameterSwapInterval];- }+ assert(window != NULL); + [window->context.nsgl.object setValues:&interval+ forParameter:NSOpenGLContextParameterSwapInterval];+ } // autoreleasepool } @@ -162,7 +161,7 @@ if (ctxconfig->client == GLFW_OPENGL_ES_API) { _glfwInputError(GLFW_API_UNAVAILABLE,- "NSGL: OpenGL ES is not available on macOS");+ "NSGL: OpenGL ES is not available via NSGL"); return GLFW_FALSE; } @@ -176,6 +175,13 @@ } } + if (ctxconfig->major >= 3 && ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)+ {+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,+ "NSGL: The compatibility profile is not available on macOS");+ return GLFW_FALSE;+ }+ // Context robustness modes (GL_KHR_robustness) are not yet supported by // macOS but are not a hard constraint, so ignore and continue @@ -334,7 +340,7 @@ forParameter:NSOpenGLContextParameterSurfaceOpacity]; } - [window->ns.view setWantsBestResolutionOpenGLSurface:window->ns.retina];+ [window->ns.view setWantsBestResolutionOpenGLSurface:window->ns.scaleFramebuffer]; [window->context.nsgl.object setView:window->ns.view]; @@ -373,4 +379,6 @@ return window->context.nsgl.object; }++#endif // _GLFW_COCOA
raylib/src/external/glfw/src/null_init.c view
@@ -24,12 +24,11 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" #include <stdlib.h>+#include <string.h> //////////////////////////////////////////////////////////////////////////@@ -40,78 +39,78 @@ { const _GLFWplatform null = {- GLFW_PLATFORM_NULL,- _glfwInitNull,- _glfwTerminateNull,- _glfwGetCursorPosNull,- _glfwSetCursorPosNull,- _glfwSetCursorModeNull,- _glfwSetRawMouseMotionNull,- _glfwRawMouseMotionSupportedNull,- _glfwCreateCursorNull,- _glfwCreateStandardCursorNull,- _glfwDestroyCursorNull,- _glfwSetCursorNull,- _glfwGetScancodeNameNull,- _glfwGetKeyScancodeNull,- _glfwSetClipboardStringNull,- _glfwGetClipboardStringNull,- _glfwInitJoysticksNull,- _glfwTerminateJoysticksNull,- _glfwPollJoystickNull,- _glfwGetMappingNameNull,- _glfwUpdateGamepadGUIDNull,- _glfwFreeMonitorNull,- _glfwGetMonitorPosNull,- _glfwGetMonitorContentScaleNull,- _glfwGetMonitorWorkareaNull,- _glfwGetVideoModesNull,- _glfwGetVideoModeNull,- _glfwGetGammaRampNull,- _glfwSetGammaRampNull,- _glfwCreateWindowNull,- _glfwDestroyWindowNull,- _glfwSetWindowTitleNull,- _glfwSetWindowIconNull,- _glfwGetWindowPosNull,- _glfwSetWindowPosNull,- _glfwGetWindowSizeNull,- _glfwSetWindowSizeNull,- _glfwSetWindowSizeLimitsNull,- _glfwSetWindowAspectRatioNull,- _glfwGetFramebufferSizeNull,- _glfwGetWindowFrameSizeNull,- _glfwGetWindowContentScaleNull,- _glfwIconifyWindowNull,- _glfwRestoreWindowNull,- _glfwMaximizeWindowNull,- _glfwShowWindowNull,- _glfwHideWindowNull,- _glfwRequestWindowAttentionNull,- _glfwFocusWindowNull,- _glfwSetWindowMonitorNull,- _glfwWindowFocusedNull,- _glfwWindowIconifiedNull,- _glfwWindowVisibleNull,- _glfwWindowMaximizedNull,- _glfwWindowHoveredNull,- _glfwFramebufferTransparentNull,- _glfwGetWindowOpacityNull,- _glfwSetWindowResizableNull,- _glfwSetWindowDecoratedNull,- _glfwSetWindowFloatingNull,- _glfwSetWindowOpacityNull,- _glfwSetWindowMousePassthroughNull,- _glfwPollEventsNull,- _glfwWaitEventsNull,- _glfwWaitEventsTimeoutNull,- _glfwPostEmptyEventNull,- _glfwGetEGLPlatformNull,- _glfwGetEGLNativeDisplayNull,- _glfwGetEGLNativeWindowNull,- _glfwGetRequiredInstanceExtensionsNull,- _glfwGetPhysicalDevicePresentationSupportNull,- _glfwCreateWindowSurfaceNull,+ .platformID = GLFW_PLATFORM_NULL,+ .init = _glfwInitNull,+ .terminate = _glfwTerminateNull,+ .getCursorPos = _glfwGetCursorPosNull,+ .setCursorPos = _glfwSetCursorPosNull,+ .setCursorMode = _glfwSetCursorModeNull,+ .setRawMouseMotion = _glfwSetRawMouseMotionNull,+ .rawMouseMotionSupported = _glfwRawMouseMotionSupportedNull,+ .createCursor = _glfwCreateCursorNull,+ .createStandardCursor = _glfwCreateStandardCursorNull,+ .destroyCursor = _glfwDestroyCursorNull,+ .setCursor = _glfwSetCursorNull,+ .getScancodeName = _glfwGetScancodeNameNull,+ .getKeyScancode = _glfwGetKeyScancodeNull,+ .setClipboardString = _glfwSetClipboardStringNull,+ .getClipboardString = _glfwGetClipboardStringNull,+ .initJoysticks = _glfwInitJoysticksNull,+ .terminateJoysticks = _glfwTerminateJoysticksNull,+ .pollJoystick = _glfwPollJoystickNull,+ .getMappingName = _glfwGetMappingNameNull,+ .updateGamepadGUID = _glfwUpdateGamepadGUIDNull,+ .freeMonitor = _glfwFreeMonitorNull,+ .getMonitorPos = _glfwGetMonitorPosNull,+ .getMonitorContentScale = _glfwGetMonitorContentScaleNull,+ .getMonitorWorkarea = _glfwGetMonitorWorkareaNull,+ .getVideoModes = _glfwGetVideoModesNull,+ .getVideoMode = _glfwGetVideoModeNull,+ .getGammaRamp = _glfwGetGammaRampNull,+ .setGammaRamp = _glfwSetGammaRampNull,+ .createWindow = _glfwCreateWindowNull,+ .destroyWindow = _glfwDestroyWindowNull,+ .setWindowTitle = _glfwSetWindowTitleNull,+ .setWindowIcon = _glfwSetWindowIconNull,+ .getWindowPos = _glfwGetWindowPosNull,+ .setWindowPos = _glfwSetWindowPosNull,+ .getWindowSize = _glfwGetWindowSizeNull,+ .setWindowSize = _glfwSetWindowSizeNull,+ .setWindowSizeLimits = _glfwSetWindowSizeLimitsNull,+ .setWindowAspectRatio = _glfwSetWindowAspectRatioNull,+ .getFramebufferSize = _glfwGetFramebufferSizeNull,+ .getWindowFrameSize = _glfwGetWindowFrameSizeNull,+ .getWindowContentScale = _glfwGetWindowContentScaleNull,+ .iconifyWindow = _glfwIconifyWindowNull,+ .restoreWindow = _glfwRestoreWindowNull,+ .maximizeWindow = _glfwMaximizeWindowNull,+ .showWindow = _glfwShowWindowNull,+ .hideWindow = _glfwHideWindowNull,+ .requestWindowAttention = _glfwRequestWindowAttentionNull,+ .focusWindow = _glfwFocusWindowNull,+ .setWindowMonitor = _glfwSetWindowMonitorNull,+ .windowFocused = _glfwWindowFocusedNull,+ .windowIconified = _glfwWindowIconifiedNull,+ .windowVisible = _glfwWindowVisibleNull,+ .windowMaximized = _glfwWindowMaximizedNull,+ .windowHovered = _glfwWindowHoveredNull,+ .framebufferTransparent = _glfwFramebufferTransparentNull,+ .getWindowOpacity = _glfwGetWindowOpacityNull,+ .setWindowResizable = _glfwSetWindowResizableNull,+ .setWindowDecorated = _glfwSetWindowDecoratedNull,+ .setWindowFloating = _glfwSetWindowFloatingNull,+ .setWindowOpacity = _glfwSetWindowOpacityNull,+ .setWindowMousePassthrough = _glfwSetWindowMousePassthroughNull,+ .pollEvents = _glfwPollEventsNull,+ .waitEvents = _glfwWaitEventsNull,+ .waitEventsTimeout = _glfwWaitEventsTimeoutNull,+ .postEmptyEvent = _glfwPostEmptyEventNull,+ .getEGLPlatform = _glfwGetEGLPlatformNull,+ .getEGLNativeDisplay = _glfwGetEGLNativeDisplayNull,+ .getEGLNativeWindow = _glfwGetEGLNativeWindowNull,+ .getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsNull,+ .getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportNull,+ .createWindowSurface = _glfwCreateWindowSurfaceNull }; *platform = null;@@ -120,6 +119,138 @@ int _glfwInitNull(void) {+ int scancode;++ memset(_glfw.null.keycodes, -1, sizeof(_glfw.null.keycodes));+ memset(_glfw.null.scancodes, -1, sizeof(_glfw.null.scancodes));++ _glfw.null.keycodes[GLFW_NULL_SC_SPACE] = GLFW_KEY_SPACE;+ _glfw.null.keycodes[GLFW_NULL_SC_APOSTROPHE] = GLFW_KEY_APOSTROPHE;+ _glfw.null.keycodes[GLFW_NULL_SC_COMMA] = GLFW_KEY_COMMA;+ _glfw.null.keycodes[GLFW_NULL_SC_MINUS] = GLFW_KEY_MINUS;+ _glfw.null.keycodes[GLFW_NULL_SC_PERIOD] = GLFW_KEY_PERIOD;+ _glfw.null.keycodes[GLFW_NULL_SC_SLASH] = GLFW_KEY_SLASH;+ _glfw.null.keycodes[GLFW_NULL_SC_0] = GLFW_KEY_0;+ _glfw.null.keycodes[GLFW_NULL_SC_1] = GLFW_KEY_1;+ _glfw.null.keycodes[GLFW_NULL_SC_2] = GLFW_KEY_2;+ _glfw.null.keycodes[GLFW_NULL_SC_3] = GLFW_KEY_3;+ _glfw.null.keycodes[GLFW_NULL_SC_4] = GLFW_KEY_4;+ _glfw.null.keycodes[GLFW_NULL_SC_5] = GLFW_KEY_5;+ _glfw.null.keycodes[GLFW_NULL_SC_6] = GLFW_KEY_6;+ _glfw.null.keycodes[GLFW_NULL_SC_7] = GLFW_KEY_7;+ _glfw.null.keycodes[GLFW_NULL_SC_8] = GLFW_KEY_8;+ _glfw.null.keycodes[GLFW_NULL_SC_9] = GLFW_KEY_9;+ _glfw.null.keycodes[GLFW_NULL_SC_SEMICOLON] = GLFW_KEY_SEMICOLON;+ _glfw.null.keycodes[GLFW_NULL_SC_EQUAL] = GLFW_KEY_EQUAL;+ _glfw.null.keycodes[GLFW_NULL_SC_A] = GLFW_KEY_A;+ _glfw.null.keycodes[GLFW_NULL_SC_B] = GLFW_KEY_B;+ _glfw.null.keycodes[GLFW_NULL_SC_C] = GLFW_KEY_C;+ _glfw.null.keycodes[GLFW_NULL_SC_D] = GLFW_KEY_D;+ _glfw.null.keycodes[GLFW_NULL_SC_E] = GLFW_KEY_E;+ _glfw.null.keycodes[GLFW_NULL_SC_F] = GLFW_KEY_F;+ _glfw.null.keycodes[GLFW_NULL_SC_G] = GLFW_KEY_G;+ _glfw.null.keycodes[GLFW_NULL_SC_H] = GLFW_KEY_H;+ _glfw.null.keycodes[GLFW_NULL_SC_I] = GLFW_KEY_I;+ _glfw.null.keycodes[GLFW_NULL_SC_J] = GLFW_KEY_J;+ _glfw.null.keycodes[GLFW_NULL_SC_K] = GLFW_KEY_K;+ _glfw.null.keycodes[GLFW_NULL_SC_L] = GLFW_KEY_L;+ _glfw.null.keycodes[GLFW_NULL_SC_M] = GLFW_KEY_M;+ _glfw.null.keycodes[GLFW_NULL_SC_N] = GLFW_KEY_N;+ _glfw.null.keycodes[GLFW_NULL_SC_O] = GLFW_KEY_O;+ _glfw.null.keycodes[GLFW_NULL_SC_P] = GLFW_KEY_P;+ _glfw.null.keycodes[GLFW_NULL_SC_Q] = GLFW_KEY_Q;+ _glfw.null.keycodes[GLFW_NULL_SC_R] = GLFW_KEY_R;+ _glfw.null.keycodes[GLFW_NULL_SC_S] = GLFW_KEY_S;+ _glfw.null.keycodes[GLFW_NULL_SC_T] = GLFW_KEY_T;+ _glfw.null.keycodes[GLFW_NULL_SC_U] = GLFW_KEY_U;+ _glfw.null.keycodes[GLFW_NULL_SC_V] = GLFW_KEY_V;+ _glfw.null.keycodes[GLFW_NULL_SC_W] = GLFW_KEY_W;+ _glfw.null.keycodes[GLFW_NULL_SC_X] = GLFW_KEY_X;+ _glfw.null.keycodes[GLFW_NULL_SC_Y] = GLFW_KEY_Y;+ _glfw.null.keycodes[GLFW_NULL_SC_Z] = GLFW_KEY_Z;+ _glfw.null.keycodes[GLFW_NULL_SC_LEFT_BRACKET] = GLFW_KEY_LEFT_BRACKET;+ _glfw.null.keycodes[GLFW_NULL_SC_BACKSLASH] = GLFW_KEY_BACKSLASH;+ _glfw.null.keycodes[GLFW_NULL_SC_RIGHT_BRACKET] = GLFW_KEY_RIGHT_BRACKET;+ _glfw.null.keycodes[GLFW_NULL_SC_GRAVE_ACCENT] = GLFW_KEY_GRAVE_ACCENT;+ _glfw.null.keycodes[GLFW_NULL_SC_WORLD_1] = GLFW_KEY_WORLD_1;+ _glfw.null.keycodes[GLFW_NULL_SC_WORLD_2] = GLFW_KEY_WORLD_2;+ _glfw.null.keycodes[GLFW_NULL_SC_ESCAPE] = GLFW_KEY_ESCAPE;+ _glfw.null.keycodes[GLFW_NULL_SC_ENTER] = GLFW_KEY_ENTER;+ _glfw.null.keycodes[GLFW_NULL_SC_TAB] = GLFW_KEY_TAB;+ _glfw.null.keycodes[GLFW_NULL_SC_BACKSPACE] = GLFW_KEY_BACKSPACE;+ _glfw.null.keycodes[GLFW_NULL_SC_INSERT] = GLFW_KEY_INSERT;+ _glfw.null.keycodes[GLFW_NULL_SC_DELETE] = GLFW_KEY_DELETE;+ _glfw.null.keycodes[GLFW_NULL_SC_RIGHT] = GLFW_KEY_RIGHT;+ _glfw.null.keycodes[GLFW_NULL_SC_LEFT] = GLFW_KEY_LEFT;+ _glfw.null.keycodes[GLFW_NULL_SC_DOWN] = GLFW_KEY_DOWN;+ _glfw.null.keycodes[GLFW_NULL_SC_UP] = GLFW_KEY_UP;+ _glfw.null.keycodes[GLFW_NULL_SC_PAGE_UP] = GLFW_KEY_PAGE_UP;+ _glfw.null.keycodes[GLFW_NULL_SC_PAGE_DOWN] = GLFW_KEY_PAGE_DOWN;+ _glfw.null.keycodes[GLFW_NULL_SC_HOME] = GLFW_KEY_HOME;+ _glfw.null.keycodes[GLFW_NULL_SC_END] = GLFW_KEY_END;+ _glfw.null.keycodes[GLFW_NULL_SC_CAPS_LOCK] = GLFW_KEY_CAPS_LOCK;+ _glfw.null.keycodes[GLFW_NULL_SC_SCROLL_LOCK] = GLFW_KEY_SCROLL_LOCK;+ _glfw.null.keycodes[GLFW_NULL_SC_NUM_LOCK] = GLFW_KEY_NUM_LOCK;+ _glfw.null.keycodes[GLFW_NULL_SC_PRINT_SCREEN] = GLFW_KEY_PRINT_SCREEN;+ _glfw.null.keycodes[GLFW_NULL_SC_PAUSE] = GLFW_KEY_PAUSE;+ _glfw.null.keycodes[GLFW_NULL_SC_F1] = GLFW_KEY_F1;+ _glfw.null.keycodes[GLFW_NULL_SC_F2] = GLFW_KEY_F2;+ _glfw.null.keycodes[GLFW_NULL_SC_F3] = GLFW_KEY_F3;+ _glfw.null.keycodes[GLFW_NULL_SC_F4] = GLFW_KEY_F4;+ _glfw.null.keycodes[GLFW_NULL_SC_F5] = GLFW_KEY_F5;+ _glfw.null.keycodes[GLFW_NULL_SC_F6] = GLFW_KEY_F6;+ _glfw.null.keycodes[GLFW_NULL_SC_F7] = GLFW_KEY_F7;+ _glfw.null.keycodes[GLFW_NULL_SC_F8] = GLFW_KEY_F8;+ _glfw.null.keycodes[GLFW_NULL_SC_F9] = GLFW_KEY_F9;+ _glfw.null.keycodes[GLFW_NULL_SC_F10] = GLFW_KEY_F10;+ _glfw.null.keycodes[GLFW_NULL_SC_F11] = GLFW_KEY_F11;+ _glfw.null.keycodes[GLFW_NULL_SC_F12] = GLFW_KEY_F12;+ _glfw.null.keycodes[GLFW_NULL_SC_F13] = GLFW_KEY_F13;+ _glfw.null.keycodes[GLFW_NULL_SC_F14] = GLFW_KEY_F14;+ _glfw.null.keycodes[GLFW_NULL_SC_F15] = GLFW_KEY_F15;+ _glfw.null.keycodes[GLFW_NULL_SC_F16] = GLFW_KEY_F16;+ _glfw.null.keycodes[GLFW_NULL_SC_F17] = GLFW_KEY_F17;+ _glfw.null.keycodes[GLFW_NULL_SC_F18] = GLFW_KEY_F18;+ _glfw.null.keycodes[GLFW_NULL_SC_F19] = GLFW_KEY_F19;+ _glfw.null.keycodes[GLFW_NULL_SC_F20] = GLFW_KEY_F20;+ _glfw.null.keycodes[GLFW_NULL_SC_F21] = GLFW_KEY_F21;+ _glfw.null.keycodes[GLFW_NULL_SC_F22] = GLFW_KEY_F22;+ _glfw.null.keycodes[GLFW_NULL_SC_F23] = GLFW_KEY_F23;+ _glfw.null.keycodes[GLFW_NULL_SC_F24] = GLFW_KEY_F24;+ _glfw.null.keycodes[GLFW_NULL_SC_F25] = GLFW_KEY_F25;+ _glfw.null.keycodes[GLFW_NULL_SC_KP_0] = GLFW_KEY_KP_0;+ _glfw.null.keycodes[GLFW_NULL_SC_KP_1] = GLFW_KEY_KP_1;+ _glfw.null.keycodes[GLFW_NULL_SC_KP_2] = GLFW_KEY_KP_2;+ _glfw.null.keycodes[GLFW_NULL_SC_KP_3] = GLFW_KEY_KP_3;+ _glfw.null.keycodes[GLFW_NULL_SC_KP_4] = GLFW_KEY_KP_4;+ _glfw.null.keycodes[GLFW_NULL_SC_KP_5] = GLFW_KEY_KP_5;+ _glfw.null.keycodes[GLFW_NULL_SC_KP_6] = GLFW_KEY_KP_6;+ _glfw.null.keycodes[GLFW_NULL_SC_KP_7] = GLFW_KEY_KP_7;+ _glfw.null.keycodes[GLFW_NULL_SC_KP_8] = GLFW_KEY_KP_8;+ _glfw.null.keycodes[GLFW_NULL_SC_KP_9] = GLFW_KEY_KP_9;+ _glfw.null.keycodes[GLFW_NULL_SC_KP_DECIMAL] = GLFW_KEY_KP_DECIMAL;+ _glfw.null.keycodes[GLFW_NULL_SC_KP_DIVIDE] = GLFW_KEY_KP_DIVIDE;+ _glfw.null.keycodes[GLFW_NULL_SC_KP_MULTIPLY] = GLFW_KEY_KP_MULTIPLY;+ _glfw.null.keycodes[GLFW_NULL_SC_KP_SUBTRACT] = GLFW_KEY_KP_SUBTRACT;+ _glfw.null.keycodes[GLFW_NULL_SC_KP_ADD] = GLFW_KEY_KP_ADD;+ _glfw.null.keycodes[GLFW_NULL_SC_KP_ENTER] = GLFW_KEY_KP_ENTER;+ _glfw.null.keycodes[GLFW_NULL_SC_KP_EQUAL] = GLFW_KEY_KP_EQUAL;+ _glfw.null.keycodes[GLFW_NULL_SC_LEFT_SHIFT] = GLFW_KEY_LEFT_SHIFT;+ _glfw.null.keycodes[GLFW_NULL_SC_LEFT_CONTROL] = GLFW_KEY_LEFT_CONTROL;+ _glfw.null.keycodes[GLFW_NULL_SC_LEFT_ALT] = GLFW_KEY_LEFT_ALT;+ _glfw.null.keycodes[GLFW_NULL_SC_LEFT_SUPER] = GLFW_KEY_LEFT_SUPER;+ _glfw.null.keycodes[GLFW_NULL_SC_RIGHT_SHIFT] = GLFW_KEY_RIGHT_SHIFT;+ _glfw.null.keycodes[GLFW_NULL_SC_RIGHT_CONTROL] = GLFW_KEY_RIGHT_CONTROL;+ _glfw.null.keycodes[GLFW_NULL_SC_RIGHT_ALT] = GLFW_KEY_RIGHT_ALT;+ _glfw.null.keycodes[GLFW_NULL_SC_RIGHT_SUPER] = GLFW_KEY_RIGHT_SUPER;+ _glfw.null.keycodes[GLFW_NULL_SC_MENU] = GLFW_KEY_MENU;++ for (scancode = GLFW_NULL_SC_FIRST; scancode < GLFW_NULL_SC_LAST; scancode++)+ {+ if (_glfw.null.keycodes[scancode] > 0)+ _glfw.null.scancodes[_glfw.null.keycodes[scancode]] = scancode;+ }+ _glfwPollMonitorsNull(); return GLFW_TRUE; }
raylib/src/external/glfw/src/null_joystick.c view
@@ -23,8 +23,6 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h"
raylib/src/external/glfw/src/null_monitor.c view
@@ -24,8 +24,6 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" @@ -111,9 +109,10 @@ return mode; } -void _glfwGetVideoModeNull(_GLFWmonitor* monitor, GLFWvidmode* mode)+GLFWbool _glfwGetVideoModeNull(_GLFWmonitor* monitor, GLFWvidmode* mode) { *mode = getVideoMode();+ return GLFW_TRUE; } GLFWbool _glfwGetGammaRampNull(_GLFWmonitor* monitor, GLFWgammaramp* ramp)@@ -130,7 +129,7 @@ float value; value = i / (float) (monitor->null.ramp.size - 1); value = powf(value, 1.f / gamma) * 65535.f + 0.5f;- value = _glfw_fminf(value, 65535.f);+ value = fminf(value, 65535.f); monitor->null.ramp.red[i] = (unsigned short) value; monitor->null.ramp.green[i] = (unsigned short) value;
raylib/src/external/glfw/src/null_platform.h view
@@ -33,6 +33,128 @@ #define GLFW_NULL_CURSOR_STATE #define GLFW_NULL_LIBRARY_CONTEXT_STATE +#define GLFW_NULL_SC_FIRST GLFW_NULL_SC_SPACE+#define GLFW_NULL_SC_SPACE 1+#define GLFW_NULL_SC_APOSTROPHE 2+#define GLFW_NULL_SC_COMMA 3+#define GLFW_NULL_SC_MINUS 4+#define GLFW_NULL_SC_PERIOD 5+#define GLFW_NULL_SC_SLASH 6+#define GLFW_NULL_SC_0 7+#define GLFW_NULL_SC_1 8+#define GLFW_NULL_SC_2 9+#define GLFW_NULL_SC_3 10+#define GLFW_NULL_SC_4 11+#define GLFW_NULL_SC_5 12+#define GLFW_NULL_SC_6 13+#define GLFW_NULL_SC_7 14+#define GLFW_NULL_SC_8 15+#define GLFW_NULL_SC_9 16+#define GLFW_NULL_SC_SEMICOLON 17+#define GLFW_NULL_SC_EQUAL 18+#define GLFW_NULL_SC_LEFT_BRACKET 19+#define GLFW_NULL_SC_BACKSLASH 20+#define GLFW_NULL_SC_RIGHT_BRACKET 21+#define GLFW_NULL_SC_GRAVE_ACCENT 22+#define GLFW_NULL_SC_WORLD_1 23+#define GLFW_NULL_SC_WORLD_2 24+#define GLFW_NULL_SC_ESCAPE 25+#define GLFW_NULL_SC_ENTER 26+#define GLFW_NULL_SC_TAB 27+#define GLFW_NULL_SC_BACKSPACE 28+#define GLFW_NULL_SC_INSERT 29+#define GLFW_NULL_SC_DELETE 30+#define GLFW_NULL_SC_RIGHT 31+#define GLFW_NULL_SC_LEFT 32+#define GLFW_NULL_SC_DOWN 33+#define GLFW_NULL_SC_UP 34+#define GLFW_NULL_SC_PAGE_UP 35+#define GLFW_NULL_SC_PAGE_DOWN 36+#define GLFW_NULL_SC_HOME 37+#define GLFW_NULL_SC_END 38+#define GLFW_NULL_SC_CAPS_LOCK 39+#define GLFW_NULL_SC_SCROLL_LOCK 40+#define GLFW_NULL_SC_NUM_LOCK 41+#define GLFW_NULL_SC_PRINT_SCREEN 42+#define GLFW_NULL_SC_PAUSE 43+#define GLFW_NULL_SC_A 44+#define GLFW_NULL_SC_B 45+#define GLFW_NULL_SC_C 46+#define GLFW_NULL_SC_D 47+#define GLFW_NULL_SC_E 48+#define GLFW_NULL_SC_F 49+#define GLFW_NULL_SC_G 50+#define GLFW_NULL_SC_H 51+#define GLFW_NULL_SC_I 52+#define GLFW_NULL_SC_J 53+#define GLFW_NULL_SC_K 54+#define GLFW_NULL_SC_L 55+#define GLFW_NULL_SC_M 56+#define GLFW_NULL_SC_N 57+#define GLFW_NULL_SC_O 58+#define GLFW_NULL_SC_P 59+#define GLFW_NULL_SC_Q 60+#define GLFW_NULL_SC_R 61+#define GLFW_NULL_SC_S 62+#define GLFW_NULL_SC_T 63+#define GLFW_NULL_SC_U 64+#define GLFW_NULL_SC_V 65+#define GLFW_NULL_SC_W 66+#define GLFW_NULL_SC_X 67+#define GLFW_NULL_SC_Y 68+#define GLFW_NULL_SC_Z 69+#define GLFW_NULL_SC_F1 70+#define GLFW_NULL_SC_F2 71+#define GLFW_NULL_SC_F3 72+#define GLFW_NULL_SC_F4 73+#define GLFW_NULL_SC_F5 74+#define GLFW_NULL_SC_F6 75+#define GLFW_NULL_SC_F7 76+#define GLFW_NULL_SC_F8 77+#define GLFW_NULL_SC_F9 78+#define GLFW_NULL_SC_F10 79+#define GLFW_NULL_SC_F11 80+#define GLFW_NULL_SC_F12 81+#define GLFW_NULL_SC_F13 82+#define GLFW_NULL_SC_F14 83+#define GLFW_NULL_SC_F15 84+#define GLFW_NULL_SC_F16 85+#define GLFW_NULL_SC_F17 86+#define GLFW_NULL_SC_F18 87+#define GLFW_NULL_SC_F19 88+#define GLFW_NULL_SC_F20 89+#define GLFW_NULL_SC_F21 90+#define GLFW_NULL_SC_F22 91+#define GLFW_NULL_SC_F23 92+#define GLFW_NULL_SC_F24 93+#define GLFW_NULL_SC_F25 94+#define GLFW_NULL_SC_KP_0 95+#define GLFW_NULL_SC_KP_1 96+#define GLFW_NULL_SC_KP_2 97+#define GLFW_NULL_SC_KP_3 98+#define GLFW_NULL_SC_KP_4 99+#define GLFW_NULL_SC_KP_5 100+#define GLFW_NULL_SC_KP_6 101+#define GLFW_NULL_SC_KP_7 102+#define GLFW_NULL_SC_KP_8 103+#define GLFW_NULL_SC_KP_9 104+#define GLFW_NULL_SC_KP_DECIMAL 105+#define GLFW_NULL_SC_KP_DIVIDE 106+#define GLFW_NULL_SC_KP_MULTIPLY 107+#define GLFW_NULL_SC_KP_SUBTRACT 108+#define GLFW_NULL_SC_KP_ADD 109+#define GLFW_NULL_SC_KP_ENTER 110+#define GLFW_NULL_SC_KP_EQUAL 111+#define GLFW_NULL_SC_LEFT_SHIFT 112+#define GLFW_NULL_SC_LEFT_CONTROL 113+#define GLFW_NULL_SC_LEFT_ALT 114+#define GLFW_NULL_SC_LEFT_SUPER 115+#define GLFW_NULL_SC_RIGHT_SHIFT 116+#define GLFW_NULL_SC_RIGHT_CONTROL 117+#define GLFW_NULL_SC_RIGHT_ALT 118+#define GLFW_NULL_SC_RIGHT_SUPER 119+#define GLFW_NULL_SC_MENU 120+#define GLFW_NULL_SC_LAST GLFW_NULL_SC_MENU // Null-specific per-window data //@@ -42,7 +164,6 @@ int ypos; int width; int height;- char* title; GLFWbool visible; GLFWbool iconified; GLFWbool maximized;@@ -68,6 +189,8 @@ int ycursor; char* clipboardString; _GLFWwindow* focusedWindow;+ uint16_t keycodes[GLFW_NULL_SC_LAST + 1];+ uint8_t scancodes[GLFW_KEY_LAST + 1]; } _GLFWlibraryNull; void _glfwPollMonitorsNull(void);@@ -81,7 +204,7 @@ void _glfwGetMonitorContentScaleNull(_GLFWmonitor* monitor, float* xscale, float* yscale); void _glfwGetMonitorWorkareaNull(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height); GLFWvidmode* _glfwGetVideoModesNull(_GLFWmonitor* monitor, int* found);-void _glfwGetVideoModeNull(_GLFWmonitor* monitor, GLFWvidmode* mode);+GLFWbool _glfwGetVideoModeNull(_GLFWmonitor* monitor, GLFWvidmode* mode); GLFWbool _glfwGetGammaRampNull(_GLFWmonitor* monitor, GLFWgammaramp* ramp); void _glfwSetGammaRampNull(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); @@ -114,7 +237,6 @@ void _glfwSetRawMouseMotionNull(_GLFWwindow *window, GLFWbool enabled); GLFWbool _glfwRawMouseMotionSupportedNull(void); void _glfwShowWindowNull(_GLFWwindow* window);-void _glfwRequestWindowAttentionNull(_GLFWwindow* window); void _glfwRequestWindowAttentionNull(_GLFWwindow* window); void _glfwHideWindowNull(_GLFWwindow* window); void _glfwFocusWindowNull(_GLFWwindow* window);
raylib/src/external/glfw/src/null_window.c view
@@ -1,8 +1,9 @@ //========================================================================-// GLFW 3.4 - www.glfw.org+// GLFW 3.4 (modified for raylib) - www.glfw.org; www.raylib.com //------------------------------------------------------------------------ // Copyright (c) 2016 Google Inc. // Copyright (c) 2016-2019 Camilla Löwy <elmindreda@glfw.org>+// Copyright (c) 2024 M374LX <wilsalx@gmail.com> // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages@@ -24,8 +25,6 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" @@ -61,12 +60,12 @@ window->null.height = mode.height; } -static void acquireMonitor(_GLFWwindow* window)+static void acquireMonitorNull(_GLFWwindow* window) { _glfwInputMonitorWindow(window->monitor, window); } -static void releaseMonitor(_GLFWwindow* window)+static void releaseMonitorNull(_GLFWwindow* window) { if (window->monitor->window != window) return;@@ -149,7 +148,7 @@ { _glfwShowWindowNull(window); _glfwFocusWindowNull(window);- acquireMonitor(window);+ acquireMonitorNull(window); if (wndconfig->centerCursor) _glfwCenterCursorInContentArea(window);@@ -170,7 +169,7 @@ void _glfwDestroyWindowNull(_GLFWwindow* window) { if (window->monitor)- releaseMonitor(window);+ releaseMonitorNull(window); if (_glfw.null.focusedWindow == window) _glfw.null.focusedWindow = NULL;@@ -205,14 +204,14 @@ } if (window->monitor)- releaseMonitor(window);+ releaseMonitorNull(window); _glfwInputWindowMonitor(window, monitor); if (window->monitor) { window->null.visible = GLFW_TRUE;- acquireMonitor(window);+ acquireMonitorNull(window); fitToMonitor(window); } else@@ -260,8 +259,9 @@ { window->null.width = width; window->null.height = height;- _glfwInputWindowSize(window, width, height); _glfwInputFramebufferSize(window, width, height);+ _glfwInputWindowDamage(window);+ _glfwInputWindowSize(window, width, height); } } @@ -341,7 +341,7 @@ _glfwInputWindowIconify(window, GLFW_TRUE); if (window->monitor)- releaseMonitor(window);+ releaseMonitorNull(window); } } @@ -353,7 +353,7 @@ _glfwInputWindowIconify(window, GLFW_FALSE); if (window->monitor)- acquireMonitor(window);+ acquireMonitorNull(window); } else if (window->null.maximized) {@@ -568,7 +568,7 @@ const char* _glfwGetScancodeNameNull(int scancode) {- if (scancode < GLFW_KEY_SPACE || scancode > GLFW_KEY_LAST)+ if (scancode < GLFW_NULL_SC_FIRST || scancode > GLFW_NULL_SC_LAST) { _glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode); return NULL;@@ -576,117 +576,117 @@ switch (scancode) {- case GLFW_KEY_APOSTROPHE:+ case GLFW_NULL_SC_APOSTROPHE: return "'";- case GLFW_KEY_COMMA:+ case GLFW_NULL_SC_COMMA: return ",";- case GLFW_KEY_MINUS:- case GLFW_KEY_KP_SUBTRACT:+ case GLFW_NULL_SC_MINUS:+ case GLFW_NULL_SC_KP_SUBTRACT: return "-";- case GLFW_KEY_PERIOD:- case GLFW_KEY_KP_DECIMAL:+ case GLFW_NULL_SC_PERIOD:+ case GLFW_NULL_SC_KP_DECIMAL: return ".";- case GLFW_KEY_SLASH:- case GLFW_KEY_KP_DIVIDE:+ case GLFW_NULL_SC_SLASH:+ case GLFW_NULL_SC_KP_DIVIDE: return "/";- case GLFW_KEY_SEMICOLON:+ case GLFW_NULL_SC_SEMICOLON: return ";";- case GLFW_KEY_EQUAL:- case GLFW_KEY_KP_EQUAL:+ case GLFW_NULL_SC_EQUAL:+ case GLFW_NULL_SC_KP_EQUAL: return "=";- case GLFW_KEY_LEFT_BRACKET:+ case GLFW_NULL_SC_LEFT_BRACKET: return "[";- case GLFW_KEY_RIGHT_BRACKET:+ case GLFW_NULL_SC_RIGHT_BRACKET: return "]";- case GLFW_KEY_KP_MULTIPLY:+ case GLFW_NULL_SC_KP_MULTIPLY: return "*";- case GLFW_KEY_KP_ADD:+ case GLFW_NULL_SC_KP_ADD: return "+";- case GLFW_KEY_BACKSLASH:- case GLFW_KEY_WORLD_1:- case GLFW_KEY_WORLD_2:+ case GLFW_NULL_SC_BACKSLASH:+ case GLFW_NULL_SC_WORLD_1:+ case GLFW_NULL_SC_WORLD_2: return "\\";- case GLFW_KEY_0:- case GLFW_KEY_KP_0:+ case GLFW_NULL_SC_0:+ case GLFW_NULL_SC_KP_0: return "0";- case GLFW_KEY_1:- case GLFW_KEY_KP_1:+ case GLFW_NULL_SC_1:+ case GLFW_NULL_SC_KP_1: return "1";- case GLFW_KEY_2:- case GLFW_KEY_KP_2:+ case GLFW_NULL_SC_2:+ case GLFW_NULL_SC_KP_2: return "2";- case GLFW_KEY_3:- case GLFW_KEY_KP_3:+ case GLFW_NULL_SC_3:+ case GLFW_NULL_SC_KP_3: return "3";- case GLFW_KEY_4:- case GLFW_KEY_KP_4:+ case GLFW_NULL_SC_4:+ case GLFW_NULL_SC_KP_4: return "4";- case GLFW_KEY_5:- case GLFW_KEY_KP_5:+ case GLFW_NULL_SC_5:+ case GLFW_NULL_SC_KP_5: return "5";- case GLFW_KEY_6:- case GLFW_KEY_KP_6:+ case GLFW_NULL_SC_6:+ case GLFW_NULL_SC_KP_6: return "6";- case GLFW_KEY_7:- case GLFW_KEY_KP_7:+ case GLFW_NULL_SC_7:+ case GLFW_NULL_SC_KP_7: return "7";- case GLFW_KEY_8:- case GLFW_KEY_KP_8:+ case GLFW_NULL_SC_8:+ case GLFW_NULL_SC_KP_8: return "8";- case GLFW_KEY_9:- case GLFW_KEY_KP_9:+ case GLFW_NULL_SC_9:+ case GLFW_NULL_SC_KP_9: return "9";- case GLFW_KEY_A:+ case GLFW_NULL_SC_A: return "a";- case GLFW_KEY_B:+ case GLFW_NULL_SC_B: return "b";- case GLFW_KEY_C:+ case GLFW_NULL_SC_C: return "c";- case GLFW_KEY_D:+ case GLFW_NULL_SC_D: return "d";- case GLFW_KEY_E:+ case GLFW_NULL_SC_E: return "e";- case GLFW_KEY_F:+ case GLFW_NULL_SC_F: return "f";- case GLFW_KEY_G:+ case GLFW_NULL_SC_G: return "g";- case GLFW_KEY_H:+ case GLFW_NULL_SC_H: return "h";- case GLFW_KEY_I:+ case GLFW_NULL_SC_I: return "i";- case GLFW_KEY_J:+ case GLFW_NULL_SC_J: return "j";- case GLFW_KEY_K:+ case GLFW_NULL_SC_K: return "k";- case GLFW_KEY_L:+ case GLFW_NULL_SC_L: return "l";- case GLFW_KEY_M:+ case GLFW_NULL_SC_M: return "m";- case GLFW_KEY_N:+ case GLFW_NULL_SC_N: return "n";- case GLFW_KEY_O:+ case GLFW_NULL_SC_O: return "o";- case GLFW_KEY_P:+ case GLFW_NULL_SC_P: return "p";- case GLFW_KEY_Q:+ case GLFW_NULL_SC_Q: return "q";- case GLFW_KEY_R:+ case GLFW_NULL_SC_R: return "r";- case GLFW_KEY_S:+ case GLFW_NULL_SC_S: return "s";- case GLFW_KEY_T:+ case GLFW_NULL_SC_T: return "t";- case GLFW_KEY_U:+ case GLFW_NULL_SC_U: return "u";- case GLFW_KEY_V:+ case GLFW_NULL_SC_V: return "v";- case GLFW_KEY_W:+ case GLFW_NULL_SC_W: return "w";- case GLFW_KEY_X:+ case GLFW_NULL_SC_X: return "x";- case GLFW_KEY_Y:+ case GLFW_NULL_SC_Y: return "y";- case GLFW_KEY_Z:+ case GLFW_NULL_SC_Z: return "z"; } @@ -695,7 +695,7 @@ int _glfwGetKeyScancodeNull(int key) {- return key;+ return _glfw.null.scancodes[key]; } void _glfwGetRequiredInstanceExtensionsNull(char** extensions)
raylib/src/external/glfw/src/osmesa_context.c view
@@ -24,15 +24,12 @@ // distribution. // //========================================================================-// Please use C89 style variable declarations in this file because VS 2010-//======================================================================== +#include "internal.h"+ #include <stdlib.h> #include <string.h> #include <assert.h>--#include "internal.h"- static void makeContextCurrentOSMesa(_GLFWwindow* window) {
raylib/src/external/glfw/src/platform.c view
@@ -1,8 +1,9 @@ //========================================================================-// GLFW 3.4 - www.glfw.org+// GLFW 3.4 (modified for raylib) - www.glfw.org; www.raylib.com //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>+// Copyright (c) 2024 M374LX <wilsalx@gmail.com> // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages@@ -24,11 +25,16 @@ // distribution. // //========================================================================-// Please use C89 style variable declarations in this file because VS 2010-//======================================================================== #include "internal.h" +#include <string.h>+#include <stdlib.h>++// These construct a string literal from individual numeric constants+#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r+#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r)+ ////////////////////////////////////////////////////////////////////////// ////// GLFW internal API ////// //////////////////////////////////////////////////////////////////////////@@ -45,12 +51,12 @@ #if defined(_GLFW_COCOA) { GLFW_PLATFORM_COCOA, _glfwConnectCocoa }, #endif-#if defined(_GLFW_X11)- { GLFW_PLATFORM_X11, _glfwConnectX11 },-#endif #if defined(_GLFW_WAYLAND) { GLFW_PLATFORM_WAYLAND, _glfwConnectWayland }, #endif+#if defined(_GLFW_X11)+ { GLFW_PLATFORM_X11, _glfwConnectX11 },+#endif }; GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform)@@ -69,14 +75,21 @@ return GLFW_FALSE; } - // Only allow the Null platform if specifically requested- if (desiredID == GLFW_PLATFORM_NULL)- return GLFW_FALSE; //_glfwConnectNull(desiredID, platform); // @raysan5- else if (count == 0)+#if defined(_GLFW_WAYLAND) && defined(_GLFW_X11)+ if (desiredID == GLFW_ANY_PLATFORM) {- _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "This binary only supports the Null platform");- return GLFW_FALSE;+ const char* const session = getenv("XDG_SESSION_TYPE");+ if (session)+ {+ // Only follow XDG_SESSION_TYPE if it is set correctly and the+ // environment looks plausble; otherwise fall back to detection+ if (strcmp(session, "wayland") == 0 && getenv("WAYLAND_DISPLAY"))+ desiredID = GLFW_PLATFORM_WAYLAND;+ else if (strcmp(session, "x11") == 0 && getenv("DISPLAY"))+ desiredID = GLFW_PLATFORM_X11;+ } }+#endif if (desiredID == GLFW_ANY_PLATFORM) {@@ -146,7 +159,9 @@ GLFWAPI const char* glfwGetVersionString(void) {- return _GLFW_VERSION_NUMBER+ return _GLFW_MAKE_VERSION(GLFW_VERSION_MAJOR,+ GLFW_VERSION_MINOR,+ GLFW_VERSION_REVISION) #if defined(_GLFW_WIN32) " Win32 WGL" #endif
raylib/src/external/glfw/src/platform.h view
@@ -25,10 +25,26 @@ // //======================================================================== +#if defined(GLFW_BUILD_WIN32_TIMER) || \+ defined(GLFW_BUILD_WIN32_MODULE) || \+ defined(GLFW_BUILD_WIN32_THREAD) || \+ defined(GLFW_BUILD_COCOA_TIMER) || \+ defined(GLFW_BUILD_POSIX_TIMER) || \+ defined(GLFW_BUILD_POSIX_MODULE) || \+ defined(GLFW_BUILD_POSIX_THREAD) || \+ defined(GLFW_BUILD_POSIX_POLL) || \+ defined(GLFW_BUILD_LINUX_JOYSTICK)+ #error "You must not define these; define zero or more _GLFW_<platform> macros instead"+#endif+ #include "null_platform.h"+#define GLFW_EXPOSE_NATIVE_EGL+#define GLFW_EXPOSE_NATIVE_OSMESA #if defined(_GLFW_WIN32) #include "win32_platform.h"+ #define GLFW_EXPOSE_NATIVE_WIN32+ #define GLFW_EXPOSE_NATIVE_WGL #else #define GLFW_WIN32_WINDOW_STATE #define GLFW_WIN32_MONITOR_STATE@@ -40,6 +56,8 @@ #if defined(_GLFW_COCOA) #include "cocoa_platform.h"+ #define GLFW_EXPOSE_NATIVE_COCOA+ #define GLFW_EXPOSE_NATIVE_NSGL #else #define GLFW_COCOA_WINDOW_STATE #define GLFW_COCOA_MONITOR_STATE@@ -51,6 +69,7 @@ #if defined(_GLFW_WAYLAND) #include "wl_platform.h"+ #define GLFW_EXPOSE_NATIVE_WAYLAND #else #define GLFW_WAYLAND_WINDOW_STATE #define GLFW_WAYLAND_MONITOR_STATE@@ -60,6 +79,8 @@ #if defined(_GLFW_X11) #include "x11_platform.h"+ #define GLFW_EXPOSE_NATIVE_X11+ #define GLFW_EXPOSE_NATIVE_GLX #else #define GLFW_X11_WINDOW_STATE #define GLFW_X11_MONITOR_STATE@@ -86,6 +107,10 @@ #endif #if (defined(_GLFW_X11) || defined(_GLFW_WAYLAND)) && defined(__linux__)+ #define GLFW_BUILD_LINUX_JOYSTICK+#endif++#if defined(GLFW_BUILD_LINUX_JOYSTICK) #include "linux_joystick.h" #else #define GLFW_LINUX_JOYSTICK_STATE@@ -141,23 +166,47 @@ GLFW_GLX_LIBRARY_CONTEXT_STATE #if defined(_WIN32)+ #define GLFW_BUILD_WIN32_THREAD+#else+ #define GLFW_BUILD_POSIX_THREAD+#endif++#if defined(GLFW_BUILD_WIN32_THREAD) #include "win32_thread.h" #define GLFW_PLATFORM_TLS_STATE GLFW_WIN32_TLS_STATE #define GLFW_PLATFORM_MUTEX_STATE GLFW_WIN32_MUTEX_STATE-#else+#elif defined(GLFW_BUILD_POSIX_THREAD) #include "posix_thread.h" #define GLFW_PLATFORM_TLS_STATE GLFW_POSIX_TLS_STATE #define GLFW_PLATFORM_MUTEX_STATE GLFW_POSIX_MUTEX_STATE #endif #if defined(_WIN32)+ #define GLFW_BUILD_WIN32_TIMER+#elif defined(__APPLE__)+ #define GLFW_BUILD_COCOA_TIMER+#else+ #define GLFW_BUILD_POSIX_TIMER+#endif++#if defined(GLFW_BUILD_WIN32_TIMER) #include "win32_time.h" #define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_WIN32_LIBRARY_TIMER_STATE-#elif defined(__APPLE__)+#elif defined(GLFW_BUILD_COCOA_TIMER) #include "cocoa_time.h" #define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_COCOA_LIBRARY_TIMER_STATE-#else+#elif defined(GLFW_BUILD_POSIX_TIMER) #include "posix_time.h" #define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_POSIX_LIBRARY_TIMER_STATE+#endif++#if defined(_WIN32)+ #define GLFW_BUILD_WIN32_MODULE+#else+ #define GLFW_BUILD_POSIX_MODULE+#endif++#if defined(_GLFW_WAYLAND) || defined(_GLFW_X11)+ #define GLFW_BUILD_POSIX_POLL #endif
raylib/src/external/glfw/src/posix_module.c view
@@ -23,11 +23,11 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_POSIX_MODULE)+ #include <dlfcn.h> //////////////////////////////////////////////////////////////////////////@@ -48,4 +48,6 @@ { return dlsym(module, name); }++#endif // GLFW_BUILD_POSIX_MODULE
raylib/src/external/glfw/src/posix_poll.c view
@@ -23,13 +23,13 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #define _GNU_SOURCE #include "internal.h" +#if defined(GLFW_BUILD_POSIX_POLL)+ #include <signal.h> #include <time.h> #include <errno.h>@@ -78,4 +78,6 @@ } } }++#endif // GLFW_BUILD_POSIX_POLL
raylib/src/external/glfw/src/posix_poll.h view
@@ -23,8 +23,6 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include <poll.h>
raylib/src/external/glfw/src/posix_thread.c view
@@ -24,11 +24,11 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_POSIX_THREAD)+ #include <assert.h> #include <string.h> @@ -102,4 +102,6 @@ assert(mutex->posix.allocated == GLFW_TRUE); pthread_mutex_unlock(&mutex->posix.handle); }++#endif // GLFW_BUILD_POSIX_THREAD
raylib/src/external/glfw/src/posix_time.c view
@@ -24,11 +24,11 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_POSIX_TIMER)+ #include <unistd.h> #include <sys/time.h> @@ -60,4 +60,6 @@ { return _glfw.timer.posix.frequency; }++#endif // GLFW_BUILD_POSIX_TIMER
raylib/src/external/glfw/src/vulkan.c view
@@ -24,8 +24,6 @@ // distribution. // //========================================================================-// Please use C89 style variable declarations in this file because VS 2010-//======================================================================== #include "internal.h"
raylib/src/external/glfw/src/wgl_context.c view
@@ -24,11 +24,11 @@ // distribution. // //========================================================================-// Please use C89 style variable declarations in this file because VS 2010-//======================================================================== #include "internal.h" +#if defined(_GLFW_WIN32)+ #include <stdlib.h> #include <assert.h> @@ -115,6 +115,23 @@ if (_glfw.wgl.EXT_colorspace) ADD_ATTRIB(WGL_COLORSPACE_EXT); }++ // NOTE: In a Parallels VM WGL_ARB_pixel_format returns fewer pixel formats than+ // DescribePixelFormat, violating the guarantees of the extension spec+ // HACK: Iterate through the minimum of both counts++ const int attrib = WGL_NUMBER_PIXEL_FORMATS_ARB;+ int extensionCount;++ if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc,+ 1, 0, 1, &attrib, &extensionCount))+ {+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,+ "WGL: Failed to retrieve pixel format attribute");+ return 0;+ }++ nativeCount = _glfw_min(nativeCount, extensionCount); } usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));@@ -330,6 +347,7 @@ static void swapIntervalWGL(int interval) { _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);+ assert(window != NULL); window->context.wgl.interval = interval; @@ -775,4 +793,6 @@ return window->context.wgl.handle; }++#endif // _GLFW_WIN32
raylib/src/external/glfw/src/win32_init.c view
@@ -1,8 +1,9 @@ //========================================================================-// GLFW 3.4 Win32 - www.glfw.org+// GLFW 3.4 Win32 (modified for raylib) - www.glfw.org; www.raylib.com //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>+// Copyright (c) 2024 M374LX <wilsalx@gmail.com> // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages@@ -24,11 +25,11 @@ // distribution. // //========================================================================-// Please use C89 style variable declarations in this file because VS 2010-//======================================================================== #include "internal.h" +#if defined(_GLFW_WIN32)+ #include <stdlib.h> static const GUID _glfw_GUID_DEVINTERFACE_HID =@@ -195,7 +196,7 @@ // Create key code translation tables //-static void createKeyTables(void)+static void createKeyTablesWin32(void) { int scancode; @@ -382,7 +383,7 @@ if (!_glfw.win32.helperWindowClass) { _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,- "WIn32: Failed to register helper window class");+ "Win32: Failed to register helper window class"); return GLFW_FALSE; } @@ -430,7 +431,6 @@ return GLFW_TRUE; } - ////////////////////////////////////////////////////////////////////////// ////// GLFW internal API ////// //////////////////////////////////////////////////////////////////////////@@ -603,78 +603,78 @@ { const _GLFWplatform win32 = {- GLFW_PLATFORM_WIN32,- _glfwInitWin32,- _glfwTerminateWin32,- _glfwGetCursorPosWin32,- _glfwSetCursorPosWin32,- _glfwSetCursorModeWin32,- _glfwSetRawMouseMotionWin32,- _glfwRawMouseMotionSupportedWin32,- _glfwCreateCursorWin32,- _glfwCreateStandardCursorWin32,- _glfwDestroyCursorWin32,- _glfwSetCursorWin32,- _glfwGetScancodeNameWin32,- _glfwGetKeyScancodeWin32,- _glfwSetClipboardStringWin32,- _glfwGetClipboardStringWin32,- _glfwInitJoysticksWin32,- _glfwTerminateJoysticksWin32,- _glfwPollJoystickWin32,- _glfwGetMappingNameWin32,- _glfwUpdateGamepadGUIDWin32,- _glfwFreeMonitorWin32,- _glfwGetMonitorPosWin32,- _glfwGetMonitorContentScaleWin32,- _glfwGetMonitorWorkareaWin32,- _glfwGetVideoModesWin32,- _glfwGetVideoModeWin32,- _glfwGetGammaRampWin32,- _glfwSetGammaRampWin32,- _glfwCreateWindowWin32,- _glfwDestroyWindowWin32,- _glfwSetWindowTitleWin32,- _glfwSetWindowIconWin32,- _glfwGetWindowPosWin32,- _glfwSetWindowPosWin32,- _glfwGetWindowSizeWin32,- _glfwSetWindowSizeWin32,- _glfwSetWindowSizeLimitsWin32,- _glfwSetWindowAspectRatioWin32,- _glfwGetFramebufferSizeWin32,- _glfwGetWindowFrameSizeWin32,- _glfwGetWindowContentScaleWin32,- _glfwIconifyWindowWin32,- _glfwRestoreWindowWin32,- _glfwMaximizeWindowWin32,- _glfwShowWindowWin32,- _glfwHideWindowWin32,- _glfwRequestWindowAttentionWin32,- _glfwFocusWindowWin32,- _glfwSetWindowMonitorWin32,- _glfwWindowFocusedWin32,- _glfwWindowIconifiedWin32,- _glfwWindowVisibleWin32,- _glfwWindowMaximizedWin32,- _glfwWindowHoveredWin32,- _glfwFramebufferTransparentWin32,- _glfwGetWindowOpacityWin32,- _glfwSetWindowResizableWin32,- _glfwSetWindowDecoratedWin32,- _glfwSetWindowFloatingWin32,- _glfwSetWindowOpacityWin32,- _glfwSetWindowMousePassthroughWin32,- _glfwPollEventsWin32,- _glfwWaitEventsWin32,- _glfwWaitEventsTimeoutWin32,- _glfwPostEmptyEventWin32,- _glfwGetEGLPlatformWin32,- _glfwGetEGLNativeDisplayWin32,- _glfwGetEGLNativeWindowWin32,- _glfwGetRequiredInstanceExtensionsWin32,- _glfwGetPhysicalDevicePresentationSupportWin32,- _glfwCreateWindowSurfaceWin32,+ .platformID = GLFW_PLATFORM_WIN32,+ .init = _glfwInitWin32,+ .terminate = _glfwTerminateWin32,+ .getCursorPos = _glfwGetCursorPosWin32,+ .setCursorPos = _glfwSetCursorPosWin32,+ .setCursorMode = _glfwSetCursorModeWin32,+ .setRawMouseMotion = _glfwSetRawMouseMotionWin32,+ .rawMouseMotionSupported = _glfwRawMouseMotionSupportedWin32,+ .createCursor = _glfwCreateCursorWin32,+ .createStandardCursor = _glfwCreateStandardCursorWin32,+ .destroyCursor = _glfwDestroyCursorWin32,+ .setCursor = _glfwSetCursorWin32,+ .getScancodeName = _glfwGetScancodeNameWin32,+ .getKeyScancode = _glfwGetKeyScancodeWin32,+ .setClipboardString = _glfwSetClipboardStringWin32,+ .getClipboardString = _glfwGetClipboardStringWin32,+ .initJoysticks = _glfwInitJoysticksWin32,+ .terminateJoysticks = _glfwTerminateJoysticksWin32,+ .pollJoystick = _glfwPollJoystickWin32,+ .getMappingName = _glfwGetMappingNameWin32,+ .updateGamepadGUID = _glfwUpdateGamepadGUIDWin32,+ .freeMonitor = _glfwFreeMonitorWin32,+ .getMonitorPos = _glfwGetMonitorPosWin32,+ .getMonitorContentScale = _glfwGetMonitorContentScaleWin32,+ .getMonitorWorkarea = _glfwGetMonitorWorkareaWin32,+ .getVideoModes = _glfwGetVideoModesWin32,+ .getVideoMode = _glfwGetVideoModeWin32,+ .getGammaRamp = _glfwGetGammaRampWin32,+ .setGammaRamp = _glfwSetGammaRampWin32,+ .createWindow = _glfwCreateWindowWin32,+ .destroyWindow = _glfwDestroyWindowWin32,+ .setWindowTitle = _glfwSetWindowTitleWin32,+ .setWindowIcon = _glfwSetWindowIconWin32,+ .getWindowPos = _glfwGetWindowPosWin32,+ .setWindowPos = _glfwSetWindowPosWin32,+ .getWindowSize = _glfwGetWindowSizeWin32,+ .setWindowSize = _glfwSetWindowSizeWin32,+ .setWindowSizeLimits = _glfwSetWindowSizeLimitsWin32,+ .setWindowAspectRatio = _glfwSetWindowAspectRatioWin32,+ .getFramebufferSize = _glfwGetFramebufferSizeWin32,+ .getWindowFrameSize = _glfwGetWindowFrameSizeWin32,+ .getWindowContentScale = _glfwGetWindowContentScaleWin32,+ .iconifyWindow = _glfwIconifyWindowWin32,+ .restoreWindow = _glfwRestoreWindowWin32,+ .maximizeWindow = _glfwMaximizeWindowWin32,+ .showWindow = _glfwShowWindowWin32,+ .hideWindow = _glfwHideWindowWin32,+ .requestWindowAttention = _glfwRequestWindowAttentionWin32,+ .focusWindow = _glfwFocusWindowWin32,+ .setWindowMonitor = _glfwSetWindowMonitorWin32,+ .windowFocused = _glfwWindowFocusedWin32,+ .windowIconified = _glfwWindowIconifiedWin32,+ .windowVisible = _glfwWindowVisibleWin32,+ .windowMaximized = _glfwWindowMaximizedWin32,+ .windowHovered = _glfwWindowHoveredWin32,+ .framebufferTransparent = _glfwFramebufferTransparentWin32,+ .getWindowOpacity = _glfwGetWindowOpacityWin32,+ .setWindowResizable = _glfwSetWindowResizableWin32,+ .setWindowDecorated = _glfwSetWindowDecoratedWin32,+ .setWindowFloating = _glfwSetWindowFloatingWin32,+ .setWindowOpacity = _glfwSetWindowOpacityWin32,+ .setWindowMousePassthrough = _glfwSetWindowMousePassthroughWin32,+ .pollEvents = _glfwPollEventsWin32,+ .waitEvents = _glfwWaitEventsWin32,+ .waitEventsTimeout = _glfwWaitEventsTimeoutWin32,+ .postEmptyEvent = _glfwPostEmptyEventWin32,+ .getEGLPlatform = _glfwGetEGLPlatformWin32,+ .getEGLNativeDisplay = _glfwGetEGLNativeDisplayWin32,+ .getEGLNativeWindow = _glfwGetEGLNativeWindowWin32,+ .getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsWin32,+ .getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportWin32,+ .createWindowSurface = _glfwCreateWindowSurfaceWin32 }; *platform = win32;@@ -686,7 +686,7 @@ if (!loadLibraries()) return GLFW_FALSE; - createKeyTables();+ createKeyTablesWin32(); _glfwUpdateKeyNamesWin32(); if (_glfwIsWindows10Version1703OrGreaterWin32())@@ -705,6 +705,9 @@ void _glfwTerminateWin32(void) {+ if (_glfw.win32.blankCursor)+ DestroyIcon((HICON) _glfw.win32.blankCursor);+ if (_glfw.win32.deviceNotificationHandle) UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle); @@ -724,4 +727,6 @@ freeLibraries(); }++#endif // _GLFW_WIN32
raylib/src/external/glfw/src/win32_joystick.c view
@@ -24,11 +24,11 @@ // distribution. // //========================================================================-// Please use C89 style variable declarations in this file because VS 2010-//======================================================================== #include "internal.h" +#if defined(_GLFW_WIN32)+ #include <stdio.h> #include <math.h> @@ -734,6 +734,13 @@ if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) dpad |= GLFW_HAT_LEFT; + // Treat invalid combinations as neither being pressed+ // while preserving what data can be preserved+ if ((dpad & GLFW_HAT_RIGHT) && (dpad & GLFW_HAT_LEFT))+ dpad &= ~(GLFW_HAT_RIGHT | GLFW_HAT_LEFT);+ if ((dpad & GLFW_HAT_UP) && (dpad & GLFW_HAT_DOWN))+ dpad &= ~(GLFW_HAT_UP | GLFW_HAT_DOWN);+ _glfwInputJoystickHat(js, 0, dpad); } @@ -755,4 +762,6 @@ original, original + 4); } }++#endif // _GLFW_WIN32
raylib/src/external/glfw/src/win32_joystick.h view
@@ -27,8 +27,6 @@ #define GLFW_WIN32_JOYSTICK_STATE _GLFWjoystickWin32 win32; #define GLFW_WIN32_LIBRARY_JOYSTICK_STATE -#define GLFW_BUILD_WIN32_MAPPINGS- // Joystick element (axis, button or slider) // typedef struct _GLFWjoyobjectWin32
raylib/src/external/glfw/src/win32_module.c view
@@ -23,11 +23,11 @@ // distribution. // //========================================================================-// Please use C89 style variable declarations in this file because VS 2010-//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_WIN32_MODULE)+ ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// //////////////////////////////////////////////////////////////////////////@@ -46,4 +46,6 @@ { return (GLFWproc) GetProcAddress((HMODULE) module, name); }++#endif // GLFW_BUILD_WIN32_MODULE
raylib/src/external/glfw/src/win32_monitor.c view
@@ -24,11 +24,11 @@ // distribution. // //========================================================================-// Please use C89 style variable declarations in this file because VS 2010-//======================================================================== #include "internal.h" +#if defined(_GLFW_WIN32)+ #include <stdlib.h> #include <string.h> #include <limits.h>@@ -470,13 +470,17 @@ return result; } -void _glfwGetVideoModeWin32(_GLFWmonitor* monitor, GLFWvidmode* mode)+GLFWbool _glfwGetVideoModeWin32(_GLFWmonitor* monitor, GLFWvidmode* mode) { DEVMODEW dm; ZeroMemory(&dm, sizeof(dm)); dm.dmSize = sizeof(dm); - EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm);+ if (!EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm))+ {+ _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to query display settings");+ return GLFW_FALSE;+ } mode->width = dm.dmPelsWidth; mode->height = dm.dmPelsHeight;@@ -485,6 +489,8 @@ &mode->redBits, &mode->greenBits, &mode->blueBits);++ return GLFW_TRUE; } GLFWbool _glfwGetGammaRampWin32(_GLFWmonitor* monitor, GLFWgammaramp* ramp)@@ -535,6 +541,13 @@ { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(NULL);++ if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)+ {+ _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Win32: Platform not initialized");+ return NULL;+ }+ return monitor->win32.publicAdapterName; } @@ -542,6 +555,15 @@ { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(NULL);++ if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)+ {+ _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Win32: Platform not initialized");+ return NULL;+ }+ return monitor->win32.publicDisplayName; }++#endif // _GLFW_WIN32
raylib/src/external/glfw/src/win32_platform.h view
@@ -424,6 +424,7 @@ GLFWbool transparent; GLFWbool scaleToMonitor; GLFWbool keymenu;+ GLFWbool showDefault; // Cached size used to filter out duplicate events int width, height;@@ -457,6 +458,8 @@ RAWINPUT* rawInput; int rawInputSize; UINT mouseTrailSize;+ // The cursor handle to use to hide the cursor (NULL or a transparent cursor)+ HCURSOR blankCursor; struct { HINSTANCE instance;@@ -606,7 +609,7 @@ void _glfwGetMonitorContentScaleWin32(_GLFWmonitor* monitor, float* xscale, float* yscale); void _glfwGetMonitorWorkareaWin32(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height); GLFWvidmode* _glfwGetVideoModesWin32(_GLFWmonitor* monitor, int* count);-void _glfwGetVideoModeWin32(_GLFWmonitor* monitor, GLFWvidmode* mode);+GLFWbool _glfwGetVideoModeWin32(_GLFWmonitor* monitor, GLFWvidmode* mode); GLFWbool _glfwGetGammaRampWin32(_GLFWmonitor* monitor, GLFWgammaramp* ramp); void _glfwSetGammaRampWin32(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
raylib/src/external/glfw/src/win32_thread.c view
@@ -24,11 +24,11 @@ // distribution. // //========================================================================-// Please use C89 style variable declarations in this file because VS 2010-//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_WIN32_THREAD)+ #include <assert.h> @@ -95,4 +95,6 @@ assert(mutex->win32.allocated == GLFW_TRUE); LeaveCriticalSection(&mutex->win32.section); }++#endif // GLFW_BUILD_WIN32_THREAD
raylib/src/external/glfw/src/win32_thread.h view
@@ -25,6 +25,11 @@ // //======================================================================== +// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for+// example to allow applications to correctly declare a GL_KHR_debug callback)+// but windows.h assumes no one will define APIENTRY before it does+#undef APIENTRY+ #include <windows.h> #define GLFW_WIN32_TLS_STATE _GLFWtlsWin32 win32;
raylib/src/external/glfw/src/win32_time.c view
@@ -24,11 +24,10 @@ // distribution. // //========================================================================-// Please use C89 style variable declarations in this file because VS 2010-//======================================================================== #include "internal.h" +#if defined(GLFW_BUILD_WIN32_TIMER) ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API //////@@ -50,4 +49,6 @@ { return _glfw.timer.win32.frequency; }++#endif // GLFW_BUILD_WIN32_TIMER
raylib/src/external/glfw/src/win32_time.h view
@@ -25,6 +25,11 @@ // //======================================================================== +// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for+// example to allow applications to correctly declare a GL_KHR_debug callback)+// but windows.h assumes no one will define APIENTRY before it does+#undef APIENTRY+ #include <windows.h> #define GLFW_WIN32_LIBRARY_TIMER_STATE _GLFWtimerWin32 win32;
raylib/src/external/glfw/src/win32_window.c view
@@ -1,8 +1,9 @@ //========================================================================-// GLFW 3.4 Win32 - www.glfw.org+// GLFW 3.4 Win32 (modified for raylib) - www.glfw.org; www.raylib.com //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>+// Copyright (c) 2024 M374LX <wilsalx@gmail.com> // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages@@ -24,11 +25,11 @@ // distribution. // //========================================================================-// Please use C89 style variable declarations in this file because VS 2010-//======================================================================== #include "internal.h" +#if defined(_GLFW_WIN32)+ #include <limits.h> #include <stdlib.h> #include <string.h>@@ -184,53 +185,38 @@ return handle; } -// Translate content area size to full window size according to styles and DPI-//-static void getFullWindowSize(DWORD style, DWORD exStyle,- int contentWidth, int contentHeight,- int* fullWidth, int* fullHeight,- UINT dpi)-{- RECT rect = { 0, 0, contentWidth, contentHeight };-- if (_glfwIsWindows10Version1607OrGreaterWin32())- AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, dpi);- else- AdjustWindowRectEx(&rect, style, FALSE, exStyle);-- *fullWidth = rect.right - rect.left;- *fullHeight = rect.bottom - rect.top;-}- // Enforce the content area aspect ratio based on which edge is being dragged // static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area) {- int xoff, yoff;- UINT dpi = USER_DEFAULT_SCREEN_DPI;+ RECT frame = {0}; const float ratio = (float) window->numer / (float) window->denom;+ const DWORD style = getWindowStyle(window);+ const DWORD exStyle = getWindowExStyle(window); if (_glfwIsWindows10Version1607OrGreaterWin32())- dpi = GetDpiForWindow(window->win32.handle);-- getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),- 0, 0, &xoff, &yoff, dpi);+ {+ AdjustWindowRectExForDpi(&frame, style, FALSE, exStyle,+ GetDpiForWindow(window->win32.handle));+ }+ else+ AdjustWindowRectEx(&frame, style, FALSE, exStyle); if (edge == WMSZ_LEFT || edge == WMSZ_BOTTOMLEFT || edge == WMSZ_RIGHT || edge == WMSZ_BOTTOMRIGHT) {- area->bottom = area->top + yoff +- (int) ((area->right - area->left - xoff) / ratio);+ area->bottom = area->top + (frame.bottom - frame.top) ++ (int) (((area->right - area->left) - (frame.right - frame.left)) / ratio); } else if (edge == WMSZ_TOPLEFT || edge == WMSZ_TOPRIGHT) {- area->top = area->bottom - yoff -- (int) ((area->right - area->left - xoff) / ratio);+ area->top = area->bottom - (frame.bottom - frame.top) -+ (int) (((area->right - area->left) - (frame.right - frame.left)) / ratio); } else if (edge == WMSZ_TOP || edge == WMSZ_BOTTOM) {- area->right = area->left + xoff +- (int) ((area->bottom - area->top - yoff) * ratio);+ area->right = area->left + (frame.right - frame.left) ++ (int) (((area->bottom - area->top) - (frame.bottom - frame.top)) * ratio); } } @@ -247,7 +233,12 @@ SetCursor(LoadCursorW(NULL, IDC_ARROW)); } else- SetCursor(NULL);+ {+ // NOTE: Via Remote Desktop, setting the cursor to NULL does not hide it.+ // HACK: When running locally, it is set to NULL, but when connected via Remote+ // Desktop, this is a transparent cursor.+ SetCursor(_glfw.win32.blankCursor);+ } } // Sets the cursor clip rect to the window content area@@ -449,7 +440,7 @@ // Make the specified window and its video mode active on its monitor //-static void acquireMonitor(_GLFWwindow* window)+static void acquireMonitorWin32(_GLFWwindow* window) { if (!_glfw.win32.acquiredMonitorCount) {@@ -470,7 +461,7 @@ // Remove the window and restore the original video mode //-static void releaseMonitor(_GLFWwindow* window)+static void releaseMonitorWin32(_GLFWwindow* window) { if (window->monitor->window != window) return;@@ -480,7 +471,7 @@ { SetThreadExecutionState(ES_CONTINUOUS); - // HACK: Restore mouse trail length saved in acquireMonitor+ // HACK: Restore mouse trail length saved in acquireMonitorWin32 SystemParametersInfoW(SPI_SETMOUSETRAILS, _glfw.win32.mouseTrailSize, 0, 0); } @@ -939,8 +930,28 @@ data = _glfw.win32.rawInput; if (data->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) {- dx = data->data.mouse.lLastX - window->win32.lastCursorPosX;- dy = data->data.mouse.lLastY - window->win32.lastCursorPosY;+ POINT pos = {0};+ int width, height;++ if (data->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP)+ {+ pos.x += GetSystemMetrics(SM_XVIRTUALSCREEN);+ pos.y += GetSystemMetrics(SM_YVIRTUALSCREEN);+ width = GetSystemMetrics(SM_CXVIRTUALSCREEN);+ height = GetSystemMetrics(SM_CYVIRTUALSCREEN);+ }+ else+ {+ width = GetSystemMetrics(SM_CXSCREEN);+ height = GetSystemMetrics(SM_CYSCREEN);+ }++ pos.x += (int) ((data->data.mouse.lLastX / 65535.f) * width);+ pos.y += (int) ((data->data.mouse.lLastY / 65535.f) * height);+ ScreenToClient(window->win32.handle, &pos);++ dx = pos.x - window->win32.lastCursorPosX;+ dy = pos.y - window->win32.lastCursorPosY; } else {@@ -1040,10 +1051,10 @@ if (window->monitor && window->win32.iconified != iconified) { if (iconified)- releaseMonitor(window);+ releaseMonitorWin32(window); else {- acquireMonitor(window);+ acquireMonitorWin32(window); fitToMonitor(window); } }@@ -1080,31 +1091,34 @@ case WM_GETMINMAXINFO: {- int xoff, yoff;- UINT dpi = USER_DEFAULT_SCREEN_DPI;+ RECT frame = {0}; MINMAXINFO* mmi = (MINMAXINFO*) lParam;+ const DWORD style = getWindowStyle(window);+ const DWORD exStyle = getWindowExStyle(window); if (window->monitor) break; if (_glfwIsWindows10Version1607OrGreaterWin32())- dpi = GetDpiForWindow(window->win32.handle);-- getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),- 0, 0, &xoff, &yoff, dpi);+ {+ AdjustWindowRectExForDpi(&frame, style, FALSE, exStyle,+ GetDpiForWindow(window->win32.handle));+ }+ else+ AdjustWindowRectEx(&frame, style, FALSE, exStyle); if (window->minwidth != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE) {- mmi->ptMinTrackSize.x = window->minwidth + xoff;- mmi->ptMinTrackSize.y = window->minheight + yoff;+ mmi->ptMinTrackSize.x = window->minwidth + frame.right - frame.left;+ mmi->ptMinTrackSize.y = window->minheight + frame.bottom - frame.top; } if (window->maxwidth != GLFW_DONT_CARE && window->maxheight != GLFW_DONT_CARE) {- mmi->ptMaxTrackSize.x = window->maxwidth + xoff;- mmi->ptMaxTrackSize.y = window->maxheight + yoff;+ mmi->ptMaxTrackSize.x = window->maxwidth + frame.right - frame.left;+ mmi->ptMaxTrackSize.y = window->maxheight + frame.bottom - frame.top; } if (!window->decorated)@@ -1263,7 +1277,7 @@ const _GLFWwndconfig* wndconfig, const _GLFWfbconfig* fbconfig) {- int xpos, ypos, fullWidth, fullHeight;+ int frameX, frameY, frameWidth, frameHeight; WCHAR* wideTitle; DWORD style = getWindowStyle(window); DWORD exStyle = getWindowExStyle(window);@@ -1301,6 +1315,34 @@ } } + if (GetSystemMetrics(SM_REMOTESESSION))+ {+ // NOTE: On Remote Desktop, setting the cursor to NULL does not hide it+ // HACK: Create a transparent cursor and always set that instead of NULL+ // When not on Remote Desktop, this handle is NULL and normal hiding is used+ if (!_glfw.win32.blankCursor)+ {+ const int cursorWidth = GetSystemMetrics(SM_CXCURSOR);+ const int cursorHeight = GetSystemMetrics(SM_CYCURSOR);++ unsigned char* cursorPixels = _glfw_calloc(cursorWidth * cursorHeight, 4);+ if (!cursorPixels)+ return GLFW_FALSE;++ // NOTE: Windows checks whether the image is fully transparent and if so+ // just ignores the alpha channel and makes the whole cursor opaque+ // HACK: Make one pixel slightly less transparent+ cursorPixels[3] = 1;++ const GLFWimage cursorImage = { cursorWidth, cursorHeight, cursorPixels };+ _glfw.win32.blankCursor = createIcon(&cursorImage, 0, 0, FALSE);+ _glfw_free(cursorPixels);++ if (!_glfw.win32.blankCursor)+ return GLFW_FALSE;+ }+ }+ if (window->monitor) { MONITORINFO mi = { sizeof(mi) };@@ -1309,10 +1351,10 @@ // NOTE: This window placement is temporary and approximate, as the // correct position and size cannot be known until the monitor // video mode has been picked in _glfwSetVideoModeWin32- xpos = mi.rcMonitor.left;- ypos = mi.rcMonitor.top;- fullWidth = mi.rcMonitor.right - mi.rcMonitor.left;- fullHeight = mi.rcMonitor.bottom - mi.rcMonitor.top;+ frameX = mi.rcMonitor.left;+ frameY = mi.rcMonitor.top;+ frameWidth = mi.rcMonitor.right - mi.rcMonitor.left;+ frameHeight = mi.rcMonitor.bottom - mi.rcMonitor.top; } else {@@ -1326,17 +1368,17 @@ if (wndconfig->xpos == GLFW_ANY_POSITION && wndconfig->ypos == GLFW_ANY_POSITION) {- xpos = CW_USEDEFAULT;- ypos = CW_USEDEFAULT;+ frameX = CW_USEDEFAULT;+ frameY = CW_USEDEFAULT; } else {- xpos = wndconfig->xpos + rect.left;- ypos = wndconfig->ypos + rect.top;+ frameX = wndconfig->xpos + rect.left;+ frameY = wndconfig->ypos + rect.top; } - fullWidth = rect.right - rect.left;- fullHeight = rect.bottom - rect.top;+ frameWidth = rect.right - rect.left;+ frameHeight = rect.bottom - rect.top; } wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);@@ -1347,8 +1389,8 @@ MAKEINTATOM(_glfw.win32.mainWindowClass), wideTitle, style,- xpos, ypos,- fullWidth, fullHeight,+ frameX, frameY,+ frameWidth, frameHeight, NULL, // No parent window NULL, // No window menu _glfw.win32.instance,@@ -1377,6 +1419,7 @@ window->win32.scaleToMonitor = wndconfig->scaleToMonitor; window->win32.keymenu = wndconfig->win32.keymenu;+ window->win32.showDefault = wndconfig->win32.showDefault; if (!window->monitor) {@@ -1492,7 +1535,7 @@ { _glfwShowWindowWin32(window); _glfwFocusWindowWin32(window);- acquireMonitor(window);+ acquireMonitorWin32(window); fitToMonitor(window); if (wndconfig->centerCursor)@@ -1514,7 +1557,7 @@ void _glfwDestroyWindowWin32(_GLFWwindow* window) { if (window->monitor)- releaseMonitor(window);+ releaseMonitorWin32(window); if (window->context.destroy) window->context.destroy(window);@@ -1635,7 +1678,7 @@ { if (window->monitor->window == window) {- acquireMonitor(window);+ acquireMonitorWin32(window); fitToMonitor(window); } }@@ -1759,7 +1802,23 @@ void _glfwShowWindowWin32(_GLFWwindow* window) {- ShowWindow(window->win32.handle, SW_SHOWNA);+ int showCommand = SW_SHOWNA;++ if (window->win32.showDefault)+ {+ // NOTE: GLFW windows currently do not seem to match the Windows 10 definition of+ // a main window, so even SW_SHOWDEFAULT does nothing+ // This definition is undocumented and can change (source: Raymond Chen)+ // HACK: Apply the STARTUPINFO show command manually if available+ STARTUPINFOW si = { sizeof(si) };+ GetStartupInfoW(&si);+ if (si.dwFlags & STARTF_USESHOWWINDOW)+ showCommand = si.wShowWindow;++ window->win32.showDefault = GLFW_FALSE;+ }++ ShowWindow(window->win32.handle, showCommand); } void _glfwHideWindowWin32(_GLFWwindow* window)@@ -1791,7 +1850,7 @@ { if (monitor->window == window) {- acquireMonitor(window);+ acquireMonitorWin32(window); fitToMonitor(window); } }@@ -1821,7 +1880,7 @@ } if (window->monitor)- releaseMonitor(window);+ releaseMonitorWin32(window); _glfwInputWindowMonitor(window, monitor); @@ -1839,7 +1898,7 @@ flags |= SWP_FRAMECHANGED; } - acquireMonitor(window);+ acquireMonitorWin32(window); GetMonitorInfoW(window->monitor->win32.handle, &mi); SetWindowPos(window->win32.handle, HWND_TOPMOST,@@ -2114,6 +2173,7 @@ // NOTE: Re-center the cursor only if it has moved since the last call, // to avoid breaking glfwWaitEvents with WM_MOUSEMOVE+ // The re-center is required in order to prevent the mouse cursor stopping at the edges of the screen. if (window->win32.lastCursorPosX != width / 2 || window->win32.lastCursorPosY != height / 2) {@@ -2131,7 +2191,7 @@ void _glfwWaitEventsTimeoutWin32(double timeout) {- MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLEVENTS);+ MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLINPUT); _glfwPollEventsWin32(); }@@ -2209,14 +2269,17 @@ const char* _glfwGetScancodeNameWin32(int scancode) {- if (scancode < 0 || scancode > (KF_EXTENDED | 0xff) ||- _glfw.win32.keycodes[scancode] == GLFW_KEY_UNKNOWN)+ if (scancode < 0 || scancode > (KF_EXTENDED | 0xff)) { _glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode); return NULL; } - return _glfw.win32.keynames[_glfw.win32.keycodes[scancode]];+ const int key = _glfw.win32.keycodes[scancode];+ if (key == GLFW_KEY_UNKNOWN)+ return NULL;++ return _glfw.win32.keynames[key]; } int _glfwGetKeyScancodeWin32(int key)@@ -2303,7 +2366,7 @@ void _glfwSetClipboardStringWin32(const char* string) {- int characterCount;+ int characterCount, tries = 0; HANDLE object; WCHAR* buffer; @@ -2331,12 +2394,20 @@ MultiByteToWideChar(CP_UTF8, 0, string, -1, buffer, characterCount); GlobalUnlock(object); - if (!OpenClipboard(_glfw.win32.helperWindowHandle))+ // NOTE: Retry clipboard opening a few times as some other application may have it+ // open and also the Windows Clipboard History reads it after each update+ while (!OpenClipboard(_glfw.win32.helperWindowHandle)) {- _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,- "Win32: Failed to open clipboard");- GlobalFree(object);- return;+ Sleep(1);+ tries++;++ if (tries == 3)+ {+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,+ "Win32: Failed to open clipboard");+ GlobalFree(object);+ return;+ } } EmptyClipboard();@@ -2348,12 +2419,21 @@ { HANDLE object; WCHAR* buffer;+ int tries = 0; - if (!OpenClipboard(_glfw.win32.helperWindowHandle))+ // NOTE: Retry clipboard opening a few times as some other application may have it+ // open and also the Windows Clipboard History reads it after each update+ while (!OpenClipboard(_glfw.win32.helperWindowHandle)) {- _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,- "Win32: Failed to open clipboard");- return NULL;+ Sleep(1);+ tries++;++ if (tries == 3)+ {+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,+ "Win32: Failed to open clipboard");+ return NULL;+ } } object = GetClipboardData(CF_UNICODETEXT);@@ -2509,4 +2589,6 @@ return window->win32.handle; }++#endif // _GLFW_WIN32
raylib/src/external/glfw/src/window.c view
@@ -25,8 +25,6 @@ // distribution. // //========================================================================-// Please use C89 style variable declarations in this file because VS 2010-//======================================================================== #include "internal.h" @@ -244,6 +242,7 @@ window->maxheight = GLFW_DONT_CARE; window->numer = GLFW_DONT_CARE; window->denom = GLFW_DONT_CARE;+ window->title = _glfw_strdup(title); if (!_glfw.platform.createWindow(window, &wndconfig, &ctxconfig, &fbconfig)) {@@ -276,6 +275,7 @@ _glfw.hints.window.focusOnShow = GLFW_TRUE; _glfw.hints.window.xpos = GLFW_ANY_POSITION; _glfw.hints.window.ypos = GLFW_ANY_POSITION;+ _glfw.hints.window.scaleFramebuffer = GLFW_TRUE; // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil, // double buffered@@ -290,9 +290,6 @@ // The default is to select the highest available refresh rate _glfw.hints.refreshRate = GLFW_DONT_CARE;-- // The default is to use full Retina resolution framebuffers- _glfw.hints.window.ns.retina = GLFW_TRUE; } GLFWAPI void glfwWindowHint(int hint, int value)@@ -376,18 +373,22 @@ case GLFW_POSITION_Y: _glfw.hints.window.ypos = value; return;- case GLFW_COCOA_RETINA_FRAMEBUFFER:- _glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;- return; case GLFW_WIN32_KEYBOARD_MENU: _glfw.hints.window.win32.keymenu = value ? GLFW_TRUE : GLFW_FALSE; return;+ case GLFW_WIN32_SHOWDEFAULT:+ _glfw.hints.window.win32.showDefault = value ? GLFW_TRUE : GLFW_FALSE;+ return; case GLFW_COCOA_GRAPHICS_SWITCHING: _glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE; return; case GLFW_SCALE_TO_MONITOR: _glfw.hints.window.scaleToMonitor = value ? GLFW_TRUE : GLFW_FALSE; return;+ case GLFW_SCALE_FRAMEBUFFER:+ case GLFW_COCOA_RETINA_FRAMEBUFFER:+ _glfw.hints.window.scaleFramebuffer = value ? GLFW_TRUE : GLFW_FALSE;+ return; case GLFW_CENTER_CURSOR: _glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE; return;@@ -494,6 +495,7 @@ *prev = window->next; } + _glfw_free(window->title); _glfw_free(window); } @@ -515,6 +517,16 @@ window->shouldClose = value; } +GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* handle)+{+ _GLFWwindow* window = (_GLFWwindow*) handle;+ assert(window != NULL);++ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);++ return window->title;+}+ GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title) { _GLFWwindow* window = (_GLFWwindow*) handle;@@ -522,7 +534,12 @@ assert(title != NULL); _GLFW_REQUIRE_INIT();++ char* prev = window->title;+ window->title = _glfw_strdup(title);+ _glfw.platform.setWindowTitle(window, title);+ _glfw_free(prev); } GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle,@@ -742,7 +759,7 @@ _GLFWwindow* window = (_GLFWwindow*) handle; assert(window != NULL); - _GLFW_REQUIRE_INIT_OR_RETURN(1.f);+ _GLFW_REQUIRE_INIT_OR_RETURN(0.f); return _glfw.platform.getWindowOpacity(window); }
raylib/src/external/glfw/src/wl_init.c view
@@ -1,7 +1,8 @@ //========================================================================-// GLFW 3.4 Wayland - www.glfw.org+// GLFW 3.4 Wayland (modified for raylib) - www.glfw.org; www.raylib.com //------------------------------------------------------------------------ // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>+// Copyright (c) 2024 M374LX <wilsalx@gmail.com> // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages@@ -23,11 +24,11 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" +#if defined(_GLFW_WAYLAND)+ #include <errno.h> #include <limits.h> #include <linux/input.h>@@ -38,14 +39,17 @@ #include <sys/timerfd.h> #include <unistd.h> #include <time.h>+#include <assert.h> #include "wayland-client-protocol.h"-#include "wayland-xdg-shell-client-protocol.h"-#include "wayland-xdg-decoration-client-protocol.h"-#include "wayland-viewporter-client-protocol.h"-#include "wayland-relative-pointer-unstable-v1-client-protocol.h"-#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"-#include "wayland-idle-inhibit-unstable-v1-client-protocol.h"+#include "xdg-shell-client-protocol.h"+#include "xdg-decoration-unstable-v1-client-protocol.h"+#include "viewporter-client-protocol.h"+#include "relative-pointer-unstable-v1-client-protocol.h"+#include "pointer-constraints-unstable-v1-client-protocol.h"+#include "fractional-scale-v1-client-protocol.h"+#include "xdg-activation-v1-client-protocol.h"+#include "idle-inhibit-unstable-v1-client-protocol.h" // NOTE: Versions of wayland-scanner prior to 1.17.91 named every global array of // wl_interface pointers 'types', making it impossible to combine several unmodified@@ -57,27 +61,35 @@ #undef types #define types _glfw_xdg_shell_types-#include "wayland-xdg-shell-client-protocol-code.h"+#include "xdg-shell-client-protocol-code.h" #undef types #define types _glfw_xdg_decoration_types-#include "wayland-xdg-decoration-client-protocol-code.h"+#include "xdg-decoration-unstable-v1-client-protocol-code.h" #undef types #define types _glfw_viewporter_types-#include "wayland-viewporter-client-protocol-code.h"+#include "viewporter-client-protocol-code.h" #undef types #define types _glfw_relative_pointer_types-#include "wayland-relative-pointer-unstable-v1-client-protocol-code.h"+#include "relative-pointer-unstable-v1-client-protocol-code.h" #undef types #define types _glfw_pointer_constraints_types-#include "wayland-pointer-constraints-unstable-v1-client-protocol-code.h"+#include "pointer-constraints-unstable-v1-client-protocol-code.h" #undef types +#define types _glfw_fractional_scale_types+#include "fractional-scale-v1-client-protocol-code.h"+#undef types++#define types _glfw_xdg_activation_types+#include "xdg-activation-v1-client-protocol-code.h"+#undef types+ #define types _glfw_idle_inhibit_types-#include "wayland-idle-inhibit-unstable-v1-client-protocol-code.h"+#include "idle-inhibit-unstable-v1-client-protocol-code.h" #undef types static void wmBaseHandlePing(void* userData,@@ -100,10 +112,9 @@ { if (strcmp(interface, "wl_compositor") == 0) {- _glfw.wl.compositorVersion = _glfw_min(3, version); _glfw.wl.compositor = wl_registry_bind(registry, name, &wl_compositor_interface,- _glfw.wl.compositorVersion);+ _glfw_min(3, version)); } else if (strcmp(interface, "wl_subcompositor") == 0) {@@ -123,10 +134,9 @@ { if (!_glfw.wl.seat) {- _glfw.wl.seatVersion = _glfw_min(4, version); _glfw.wl.seat = wl_registry_bind(registry, name, &wl_seat_interface,- _glfw.wl.seatVersion);+ _glfw_min(4, version)); _glfwAddSeatListenerWayland(_glfw.wl.seat); } }@@ -178,6 +188,20 @@ &zwp_idle_inhibit_manager_v1_interface, 1); }+ else if (strcmp(interface, "xdg_activation_v1") == 0)+ {+ _glfw.wl.activationManager =+ wl_registry_bind(registry, name,+ &xdg_activation_v1_interface,+ 1);+ }+ else if (strcmp(interface, "wp_fractional_scale_manager_v1") == 0)+ {+ _glfw.wl.fractionalScaleManager =+ wl_registry_bind(registry, name,+ &wp_fractional_scale_manager_v1_interface,+ 1);+ } } static void registryHandleGlobalRemove(void* userData,@@ -202,9 +226,39 @@ registryHandleGlobalRemove }; +void libdecorHandleError(struct libdecor* context,+ enum libdecor_error error,+ const char* message)+{+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: libdecor error %u: %s",+ error, message);+}++static const struct libdecor_interface libdecorInterface =+{+ libdecorHandleError+};++static void libdecorReadyCallback(void* userData,+ struct wl_callback* callback,+ uint32_t time)+{+ _glfw.wl.libdecor.ready = GLFW_TRUE;++ assert(_glfw.wl.libdecor.callback == callback);+ wl_callback_destroy(_glfw.wl.libdecor.callback);+ _glfw.wl.libdecor.callback = NULL;+}++static const struct wl_callback_listener libdecorReadyListener =+{+ libdecorReadyCallback+};+ // Create key code translation tables //-static void createKeyTables(void)+static void createKeyTablesWayland(void) { memset(_glfw.wl.keycodes, -1, sizeof(_glfw.wl.keycodes)); memset(_glfw.wl.scancodes, -1, sizeof(_glfw.wl.scancodes));@@ -337,7 +391,7 @@ static GLFWbool loadCursorTheme(void) {- int cursorSize = 32;+ int cursorSize = 16; const char* sizeString = getenv("XCURSOR_SIZE"); if (sizeString)@@ -376,86 +430,86 @@ { const _GLFWplatform wayland = {- GLFW_PLATFORM_WAYLAND,- _glfwInitWayland,- _glfwTerminateWayland,- _glfwGetCursorPosWayland,- _glfwSetCursorPosWayland,- _glfwSetCursorModeWayland,- _glfwSetRawMouseMotionWayland,- _glfwRawMouseMotionSupportedWayland,- _glfwCreateCursorWayland,- _glfwCreateStandardCursorWayland,- _glfwDestroyCursorWayland,- _glfwSetCursorWayland,- _glfwGetScancodeNameWayland,- _glfwGetKeyScancodeWayland,- _glfwSetClipboardStringWayland,- _glfwGetClipboardStringWayland,-#if defined(__linux__)- _glfwInitJoysticksLinux,- _glfwTerminateJoysticksLinux,- _glfwPollJoystickLinux,- _glfwGetMappingNameLinux,- _glfwUpdateGamepadGUIDLinux,+ .platformID = GLFW_PLATFORM_WAYLAND,+ .init = _glfwInitWayland,+ .terminate = _glfwTerminateWayland,+ .getCursorPos = _glfwGetCursorPosWayland,+ .setCursorPos = _glfwSetCursorPosWayland,+ .setCursorMode = _glfwSetCursorModeWayland,+ .setRawMouseMotion = _glfwSetRawMouseMotionWayland,+ .rawMouseMotionSupported = _glfwRawMouseMotionSupportedWayland,+ .createCursor = _glfwCreateCursorWayland,+ .createStandardCursor = _glfwCreateStandardCursorWayland,+ .destroyCursor = _glfwDestroyCursorWayland,+ .setCursor = _glfwSetCursorWayland,+ .getScancodeName = _glfwGetScancodeNameWayland,+ .getKeyScancode = _glfwGetKeyScancodeWayland,+ .setClipboardString = _glfwSetClipboardStringWayland,+ .getClipboardString = _glfwGetClipboardStringWayland,+#if defined(GLFW_BUILD_LINUX_JOYSTICK)+ .initJoysticks = _glfwInitJoysticksLinux,+ .terminateJoysticks = _glfwTerminateJoysticksLinux,+ .pollJoystick = _glfwPollJoystickLinux,+ .getMappingName = _glfwGetMappingNameLinux,+ .updateGamepadGUID = _glfwUpdateGamepadGUIDLinux, #else- _glfwInitJoysticksNull,- _glfwTerminateJoysticksNull,- _glfwPollJoystickNull,- _glfwGetMappingNameNull,- _glfwUpdateGamepadGUIDNull,+ .initJoysticks = _glfwInitJoysticksNull,+ .terminateJoysticks = _glfwTerminateJoysticksNull,+ .pollJoystick = _glfwPollJoystickNull,+ .getMappingName = _glfwGetMappingNameNull,+ .updateGamepadGUID = _glfwUpdateGamepadGUIDNull, #endif- _glfwFreeMonitorWayland,- _glfwGetMonitorPosWayland,- _glfwGetMonitorContentScaleWayland,- _glfwGetMonitorWorkareaWayland,- _glfwGetVideoModesWayland,- _glfwGetVideoModeWayland,- _glfwGetGammaRampWayland,- _glfwSetGammaRampWayland,- _glfwCreateWindowWayland,- _glfwDestroyWindowWayland,- _glfwSetWindowTitleWayland,- _glfwSetWindowIconWayland,- _glfwGetWindowPosWayland,- _glfwSetWindowPosWayland,- _glfwGetWindowSizeWayland,- _glfwSetWindowSizeWayland,- _glfwSetWindowSizeLimitsWayland,- _glfwSetWindowAspectRatioWayland,- _glfwGetFramebufferSizeWayland,- _glfwGetWindowFrameSizeWayland,- _glfwGetWindowContentScaleWayland,- _glfwIconifyWindowWayland,- _glfwRestoreWindowWayland,- _glfwMaximizeWindowWayland,- _glfwShowWindowWayland,- _glfwHideWindowWayland,- _glfwRequestWindowAttentionWayland,- _glfwFocusWindowWayland,- _glfwSetWindowMonitorWayland,- _glfwWindowFocusedWayland,- _glfwWindowIconifiedWayland,- _glfwWindowVisibleWayland,- _glfwWindowMaximizedWayland,- _glfwWindowHoveredWayland,- _glfwFramebufferTransparentWayland,- _glfwGetWindowOpacityWayland,- _glfwSetWindowResizableWayland,- _glfwSetWindowDecoratedWayland,- _glfwSetWindowFloatingWayland,- _glfwSetWindowOpacityWayland,- _glfwSetWindowMousePassthroughWayland,- _glfwPollEventsWayland,- _glfwWaitEventsWayland,- _glfwWaitEventsTimeoutWayland,- _glfwPostEmptyEventWayland,- _glfwGetEGLPlatformWayland,- _glfwGetEGLNativeDisplayWayland,- _glfwGetEGLNativeWindowWayland,- _glfwGetRequiredInstanceExtensionsWayland,- _glfwGetPhysicalDevicePresentationSupportWayland,- _glfwCreateWindowSurfaceWayland,+ .freeMonitor = _glfwFreeMonitorWayland,+ .getMonitorPos = _glfwGetMonitorPosWayland,+ .getMonitorContentScale = _glfwGetMonitorContentScaleWayland,+ .getMonitorWorkarea = _glfwGetMonitorWorkareaWayland,+ .getVideoModes = _glfwGetVideoModesWayland,+ .getVideoMode = _glfwGetVideoModeWayland,+ .getGammaRamp = _glfwGetGammaRampWayland,+ .setGammaRamp = _glfwSetGammaRampWayland,+ .createWindow = _glfwCreateWindowWayland,+ .destroyWindow = _glfwDestroyWindowWayland,+ .setWindowTitle = _glfwSetWindowTitleWayland,+ .setWindowIcon = _glfwSetWindowIconWayland,+ .getWindowPos = _glfwGetWindowPosWayland,+ .setWindowPos = _glfwSetWindowPosWayland,+ .getWindowSize = _glfwGetWindowSizeWayland,+ .setWindowSize = _glfwSetWindowSizeWayland,+ .setWindowSizeLimits = _glfwSetWindowSizeLimitsWayland,+ .setWindowAspectRatio = _glfwSetWindowAspectRatioWayland,+ .getFramebufferSize = _glfwGetFramebufferSizeWayland,+ .getWindowFrameSize = _glfwGetWindowFrameSizeWayland,+ .getWindowContentScale = _glfwGetWindowContentScaleWayland,+ .iconifyWindow = _glfwIconifyWindowWayland,+ .restoreWindow = _glfwRestoreWindowWayland,+ .maximizeWindow = _glfwMaximizeWindowWayland,+ .showWindow = _glfwShowWindowWayland,+ .hideWindow = _glfwHideWindowWayland,+ .requestWindowAttention = _glfwRequestWindowAttentionWayland,+ .focusWindow = _glfwFocusWindowWayland,+ .setWindowMonitor = _glfwSetWindowMonitorWayland,+ .windowFocused = _glfwWindowFocusedWayland,+ .windowIconified = _glfwWindowIconifiedWayland,+ .windowVisible = _glfwWindowVisibleWayland,+ .windowMaximized = _glfwWindowMaximizedWayland,+ .windowHovered = _glfwWindowHoveredWayland,+ .framebufferTransparent = _glfwFramebufferTransparentWayland,+ .getWindowOpacity = _glfwGetWindowOpacityWayland,+ .setWindowResizable = _glfwSetWindowResizableWayland,+ .setWindowDecorated = _glfwSetWindowDecoratedWayland,+ .setWindowFloating = _glfwSetWindowFloatingWayland,+ .setWindowOpacity = _glfwSetWindowOpacityWayland,+ .setWindowMousePassthrough = _glfwSetWindowMousePassthroughWayland,+ .pollEvents = _glfwPollEventsWayland,+ .waitEvents = _glfwWaitEventsWayland,+ .waitEventsTimeout = _glfwWaitEventsTimeoutWayland,+ .postEmptyEvent = _glfwPostEmptyEventWayland,+ .getEGLPlatform = _glfwGetEGLPlatformWayland,+ .getEGLNativeDisplay = _glfwGetEGLNativeDisplayWayland,+ .getEGLNativeWindow = _glfwGetEGLNativeWindowWayland,+ .getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsWayland,+ .getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportWayland,+ .createWindowSurface = _glfwCreateWindowSurfaceWayland }; void* module = _glfwPlatformLoadModule("libwayland-client.so.0");@@ -507,6 +561,8 @@ _glfw.wl.keyRepeatTimerfd = -1; _glfw.wl.cursorTimerfd = -1; + _glfw.wl.tag = glfwGetVersionString();+ _glfw.wl.client.display_flush = (PFN_wl_display_flush) _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_flush"); _glfw.wl.client.display_cancel_read = (PFN_wl_display_cancel_read)@@ -537,6 +593,10 @@ _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_user_data"); _glfw.wl.client.proxy_set_user_data = (PFN_wl_proxy_set_user_data) _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_set_user_data");+ _glfw.wl.client.proxy_get_tag = (PFN_wl_proxy_get_tag)+ _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_tag");+ _glfw.wl.client.proxy_set_tag = (PFN_wl_proxy_set_tag)+ _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_set_tag"); _glfw.wl.client.proxy_get_version = (PFN_wl_proxy_get_version) _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_version"); _glfw.wl.client.proxy_marshal_flags = (PFN_wl_proxy_marshal_flags)@@ -556,7 +616,9 @@ !_glfw.wl.client.proxy_marshal_constructor || !_glfw.wl.client.proxy_marshal_constructor_versioned || !_glfw.wl.client.proxy_get_user_data ||- !_glfw.wl.client.proxy_set_user_data)+ !_glfw.wl.client.proxy_set_user_data ||+ !_glfw.wl.client.proxy_get_tag ||+ !_glfw.wl.client.proxy_set_tag) { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Failed to load libwayland-client entry point");@@ -644,10 +706,123 @@ _glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym) _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym"); + if (!_glfw.wl.xkb.context_new ||+ !_glfw.wl.xkb.context_unref ||+ !_glfw.wl.xkb.keymap_new_from_string ||+ !_glfw.wl.xkb.keymap_unref ||+ !_glfw.wl.xkb.keymap_mod_get_index ||+ !_glfw.wl.xkb.keymap_key_repeats ||+ !_glfw.wl.xkb.keymap_key_get_syms_by_level ||+ !_glfw.wl.xkb.state_new ||+ !_glfw.wl.xkb.state_unref ||+ !_glfw.wl.xkb.state_key_get_syms ||+ !_glfw.wl.xkb.state_update_mask ||+ !_glfw.wl.xkb.state_key_get_layout ||+ !_glfw.wl.xkb.state_mod_index_is_active ||+ !_glfw.wl.xkb.compose_table_new_from_locale ||+ !_glfw.wl.xkb.compose_table_unref ||+ !_glfw.wl.xkb.compose_state_new ||+ !_glfw.wl.xkb.compose_state_unref ||+ !_glfw.wl.xkb.compose_state_feed ||+ !_glfw.wl.xkb.compose_state_get_status ||+ !_glfw.wl.xkb.compose_state_get_one_sym)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to load all entry points from libxkbcommon");+ return GLFW_FALSE;+ }++ if (_glfw.hints.init.wl.libdecorMode == GLFW_WAYLAND_PREFER_LIBDECOR)+ _glfw.wl.libdecor.handle = _glfwPlatformLoadModule("libdecor-0.so.0");++ if (_glfw.wl.libdecor.handle)+ {+ _glfw.wl.libdecor.libdecor_new_ = (PFN_libdecor_new)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_new");+ _glfw.wl.libdecor.libdecor_unref_ = (PFN_libdecor_unref)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_unref");+ _glfw.wl.libdecor.libdecor_get_fd_ = (PFN_libdecor_get_fd)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_get_fd");+ _glfw.wl.libdecor.libdecor_dispatch_ = (PFN_libdecor_dispatch)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_dispatch");+ _glfw.wl.libdecor.libdecor_decorate_ = (PFN_libdecor_decorate)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_decorate");+ _glfw.wl.libdecor.libdecor_frame_unref_ = (PFN_libdecor_frame_unref)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unref");+ _glfw.wl.libdecor.libdecor_frame_set_app_id_ = (PFN_libdecor_frame_set_app_id)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_app_id");+ _glfw.wl.libdecor.libdecor_frame_set_title_ = (PFN_libdecor_frame_set_title)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_title");+ _glfw.wl.libdecor.libdecor_frame_set_minimized_ = (PFN_libdecor_frame_set_minimized)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_minimized");+ _glfw.wl.libdecor.libdecor_frame_set_fullscreen_ = (PFN_libdecor_frame_set_fullscreen)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_fullscreen");+ _glfw.wl.libdecor.libdecor_frame_unset_fullscreen_ = (PFN_libdecor_frame_unset_fullscreen)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_fullscreen");+ _glfw.wl.libdecor.libdecor_frame_map_ = (PFN_libdecor_frame_map)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_map");+ _glfw.wl.libdecor.libdecor_frame_commit_ = (PFN_libdecor_frame_commit)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_commit");+ _glfw.wl.libdecor.libdecor_frame_set_min_content_size_ = (PFN_libdecor_frame_set_min_content_size)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_min_content_size");+ _glfw.wl.libdecor.libdecor_frame_set_max_content_size_ = (PFN_libdecor_frame_set_max_content_size)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_max_content_size");+ _glfw.wl.libdecor.libdecor_frame_set_maximized_ = (PFN_libdecor_frame_set_maximized)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_maximized");+ _glfw.wl.libdecor.libdecor_frame_unset_maximized_ = (PFN_libdecor_frame_unset_maximized)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_maximized");+ _glfw.wl.libdecor.libdecor_frame_set_capabilities_ = (PFN_libdecor_frame_set_capabilities)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_capabilities");+ _glfw.wl.libdecor.libdecor_frame_unset_capabilities_ = (PFN_libdecor_frame_unset_capabilities)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_capabilities");+ _glfw.wl.libdecor.libdecor_frame_set_visibility_ = (PFN_libdecor_frame_set_visibility)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_visibility");+ _glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ = (PFN_libdecor_frame_get_xdg_toplevel)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_get_xdg_toplevel");+ _glfw.wl.libdecor.libdecor_configuration_get_content_size_ = (PFN_libdecor_configuration_get_content_size)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_configuration_get_content_size");+ _glfw.wl.libdecor.libdecor_configuration_get_window_state_ = (PFN_libdecor_configuration_get_window_state)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_configuration_get_window_state");+ _glfw.wl.libdecor.libdecor_state_new_ = (PFN_libdecor_state_new)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_state_new");+ _glfw.wl.libdecor.libdecor_state_free_ = (PFN_libdecor_state_free)+ _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_state_free");++ if (!_glfw.wl.libdecor.libdecor_new_ ||+ !_glfw.wl.libdecor.libdecor_unref_ ||+ !_glfw.wl.libdecor.libdecor_get_fd_ ||+ !_glfw.wl.libdecor.libdecor_dispatch_ ||+ !_glfw.wl.libdecor.libdecor_decorate_ ||+ !_glfw.wl.libdecor.libdecor_frame_unref_ ||+ !_glfw.wl.libdecor.libdecor_frame_set_app_id_ ||+ !_glfw.wl.libdecor.libdecor_frame_set_title_ ||+ !_glfw.wl.libdecor.libdecor_frame_set_minimized_ ||+ !_glfw.wl.libdecor.libdecor_frame_set_fullscreen_ ||+ !_glfw.wl.libdecor.libdecor_frame_unset_fullscreen_ ||+ !_glfw.wl.libdecor.libdecor_frame_map_ ||+ !_glfw.wl.libdecor.libdecor_frame_commit_ ||+ !_glfw.wl.libdecor.libdecor_frame_set_min_content_size_ ||+ !_glfw.wl.libdecor.libdecor_frame_set_max_content_size_ ||+ !_glfw.wl.libdecor.libdecor_frame_set_maximized_ ||+ !_glfw.wl.libdecor.libdecor_frame_unset_maximized_ ||+ !_glfw.wl.libdecor.libdecor_frame_set_capabilities_ ||+ !_glfw.wl.libdecor.libdecor_frame_unset_capabilities_ ||+ !_glfw.wl.libdecor.libdecor_frame_set_visibility_ ||+ !_glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ ||+ !_glfw.wl.libdecor.libdecor_configuration_get_content_size_ ||+ !_glfw.wl.libdecor.libdecor_configuration_get_window_state_ ||+ !_glfw.wl.libdecor.libdecor_state_new_ ||+ !_glfw.wl.libdecor.libdecor_state_free_)+ {+ _glfwPlatformFreeModule(_glfw.wl.libdecor.handle);+ memset(&_glfw.wl.libdecor, 0, sizeof(_glfw.wl.libdecor));+ }+ }+ _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display); wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL); - createKeyTables();+ createKeyTablesWayland(); _glfw.wl.xkb.context = xkb_context_new(0); if (!_glfw.wl.xkb.context)@@ -663,13 +838,27 @@ // Sync so we got all initial output events wl_display_roundtrip(_glfw.wl.display); -#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION- if (_glfw.wl.seatVersion >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)+ if (_glfw.wl.libdecor.handle) {+ _glfw.wl.libdecor.context = libdecor_new(_glfw.wl.display, &libdecorInterface);+ if (_glfw.wl.libdecor.context)+ {+ // Perform an initial dispatch and flush to get the init started+ libdecor_dispatch(_glfw.wl.libdecor.context, 0);++ // Create sync point to "know" when libdecor is ready for use+ _glfw.wl.libdecor.callback = wl_display_sync(_glfw.wl.display);+ wl_callback_add_listener(_glfw.wl.libdecor.callback,+ &libdecorReadyListener,+ NULL);+ }+ }++ if (wl_seat_get_version(_glfw.wl.seat) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)+ { _glfw.wl.keyRepeatTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); }-#endif if (!_glfw.wl.wmBase) {@@ -704,6 +893,22 @@ _glfwTerminateEGL(); _glfwTerminateOSMesa(); + if (_glfw.wl.libdecor.context)+ {+ // Allow libdecor to finish receiving all its requested globals+ // and ensure the associated sync callback object is destroyed+ while (!_glfw.wl.libdecor.ready)+ _glfwWaitEventsWayland();++ libdecor_unref(_glfw.wl.libdecor.context);+ }++ if (_glfw.wl.libdecor.handle)+ {+ _glfwPlatformFreeModule(_glfw.wl.libdecor.handle);+ _glfw.wl.libdecor.handle = NULL;+ }+ if (_glfw.wl.egl.handle) { _glfwPlatformFreeModule(_glfw.wl.egl.handle);@@ -775,6 +980,10 @@ zwp_pointer_constraints_v1_destroy(_glfw.wl.pointerConstraints); if (_glfw.wl.idleInhibitManager) zwp_idle_inhibit_manager_v1_destroy(_glfw.wl.idleInhibitManager);+ if (_glfw.wl.activationManager)+ xdg_activation_v1_destroy(_glfw.wl.activationManager);+ if (_glfw.wl.fractionalScaleManager)+ wp_fractional_scale_manager_v1_destroy(_glfw.wl.fractionalScaleManager); if (_glfw.wl.registry) wl_registry_destroy(_glfw.wl.registry); if (_glfw.wl.display)@@ -790,4 +999,6 @@ _glfw_free(_glfw.wl.clipboardString); }++#endif // _GLFW_WAYLAND
raylib/src/external/glfw/src/wl_monitor.c view
@@ -23,11 +23,11 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" +#if defined(_GLFW_WAYLAND)+ #include <stdio.h> #include <stdlib.h> #include <string.h>@@ -116,19 +116,18 @@ for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next) {- for (int i = 0; i < window->wl.monitorsCount; i++)+ for (size_t i = 0; i < window->wl.outputScaleCount; i++) {- if (window->wl.monitors[i] == monitor)+ if (window->wl.outputScales[i].output == monitor->wl.output) {- _glfwUpdateContentScaleWayland(window);+ window->wl.outputScales[i].factor = monitor->wl.scale;+ _glfwUpdateBufferScaleFromOutputsWayland(window); break; } } } } -#ifdef WL_OUTPUT_NAME_SINCE_VERSION- void outputHandleName(void* userData, struct wl_output* wl_output, const char* name) { struct _GLFWmonitor* monitor = userData;@@ -142,18 +141,14 @@ { } -#endif // WL_OUTPUT_NAME_SINCE_VERSION- static const struct wl_output_listener outputListener = { outputHandleGeometry, outputHandleMode, outputHandleDone, outputHandleScale,-#ifdef WL_OUTPUT_NAME_SINCE_VERSION outputHandleName, outputHandleDescription,-#endif }; @@ -170,11 +165,7 @@ return; } -#ifdef WL_OUTPUT_NAME_SINCE_VERSION version = _glfw_min(version, WL_OUTPUT_NAME_SINCE_VERSION);-#else- version = 2;-#endif struct wl_output* output = wl_registry_bind(_glfw.wl.registry, name,@@ -189,6 +180,7 @@ monitor->wl.output = output; monitor->wl.name = name; + wl_proxy_set_tag((struct wl_proxy*) output, &_glfw.wl.tag); wl_output_add_listener(output, &outputListener, monitor); } @@ -240,9 +232,10 @@ return monitor->modes; } -void _glfwGetVideoModeWayland(_GLFWmonitor* monitor, GLFWvidmode* mode)+GLFWbool _glfwGetVideoModeWayland(_GLFWmonitor* monitor, GLFWvidmode* mode) { *mode = monitor->modes[monitor->wl.currentMode];+ return GLFW_TRUE; } GLFWbool _glfwGetGammaRampWayland(_GLFWmonitor* monitor, GLFWgammaramp* ramp)@@ -267,6 +260,15 @@ { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(NULL);++ if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND)+ {+ _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Wayland: Platform not initialized");+ return NULL;+ }+ return monitor->wl.output; }++#endif // _GLFW_WAYLAND
raylib/src/external/glfw/src/wl_platform.h view
@@ -28,6 +28,8 @@ #include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon-compose.h> +#include <stdbool.h>+ typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; typedef struct VkWaylandSurfaceCreateInfoKHR@@ -61,6 +63,8 @@ typedef struct wl_proxy* (* PFN_wl_proxy_marshal_constructor_versioned)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,...); typedef void* (* PFN_wl_proxy_get_user_data)(struct wl_proxy*); typedef void (* PFN_wl_proxy_set_user_data)(struct wl_proxy*,void*);+typedef void (* PFN_wl_proxy_set_tag)(struct wl_proxy*,const char*const*);+typedef const char* const* (* PFN_wl_proxy_get_tag)(struct wl_proxy*); typedef uint32_t (* PFN_wl_proxy_get_version)(struct wl_proxy*); typedef struct wl_proxy* (* PFN_wl_proxy_marshal_flags)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,uint32_t,...); #define wl_display_flush _glfw.wl.client.display_flush@@ -78,10 +82,13 @@ #define wl_proxy_marshal_constructor_versioned _glfw.wl.client.proxy_marshal_constructor_versioned #define wl_proxy_get_user_data _glfw.wl.client.proxy_get_user_data #define wl_proxy_set_user_data _glfw.wl.client.proxy_set_user_data+#define wl_proxy_get_tag _glfw.wl.client.proxy_get_tag+#define wl_proxy_set_tag _glfw.wl.client.proxy_set_tag #define wl_proxy_get_version _glfw.wl.client.proxy_get_version #define wl_proxy_marshal_flags _glfw.wl.client.proxy_marshal_flags struct wl_shm;+struct wl_output; #define wl_display_interface _glfw_wl_display_interface #define wl_subcompositor_interface _glfw_wl_subcompositor_interface@@ -122,6 +129,10 @@ #define xdg_surface_interface _glfw_xdg_surface_interface #define xdg_toplevel_interface _glfw_xdg_toplevel_interface #define xdg_wm_base_interface _glfw_xdg_wm_base_interface+#define xdg_activation_v1_interface _glfw_xdg_activation_v1_interface+#define xdg_activation_token_v1_interface _glfw_xdg_activation_token_v1_interface+#define wl_surface_interface _glfw_wl_surface_interface+#define wp_fractional_scale_v1_interface _glfw_wp_fractional_scale_v1_interface #define GLFW_WAYLAND_WINDOW_STATE _GLFWwindowWayland wl; #define GLFW_WAYLAND_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wl;@@ -198,21 +209,128 @@ #define xkb_compose_state_get_status _glfw.wl.xkb.compose_state_get_status #define xkb_compose_state_get_one_sym _glfw.wl.xkb.compose_state_get_one_sym -typedef enum _GLFWdecorationSideWayland+struct libdecor;+struct libdecor_frame;+struct libdecor_state;+struct libdecor_configuration;++enum libdecor_error {- mainWindow,- topDecoration,- leftDecoration,- rightDecoration,- bottomDecoration,-} _GLFWdecorationSideWayland;+ LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE,+ LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION,+}; -typedef struct _GLFWdecorationWayland+enum libdecor_window_state {+ LIBDECOR_WINDOW_STATE_NONE = 0,+ LIBDECOR_WINDOW_STATE_ACTIVE = 1,+ LIBDECOR_WINDOW_STATE_MAXIMIZED = 2,+ LIBDECOR_WINDOW_STATE_FULLSCREEN = 4,+ LIBDECOR_WINDOW_STATE_TILED_LEFT = 8,+ LIBDECOR_WINDOW_STATE_TILED_RIGHT = 16,+ LIBDECOR_WINDOW_STATE_TILED_TOP = 32,+ LIBDECOR_WINDOW_STATE_TILED_BOTTOM = 64+};++enum libdecor_capabilities+{+ LIBDECOR_ACTION_MOVE = 1,+ LIBDECOR_ACTION_RESIZE = 2,+ LIBDECOR_ACTION_MINIMIZE = 4,+ LIBDECOR_ACTION_FULLSCREEN = 8,+ LIBDECOR_ACTION_CLOSE = 16+};++struct libdecor_interface+{+ void (* error)(struct libdecor*,enum libdecor_error,const char*);+ void (* reserved0)(void);+ void (* reserved1)(void);+ void (* reserved2)(void);+ void (* reserved3)(void);+ void (* reserved4)(void);+ void (* reserved5)(void);+ void (* reserved6)(void);+ void (* reserved7)(void);+ void (* reserved8)(void);+ void (* reserved9)(void);+};++struct libdecor_frame_interface+{+ void (* configure)(struct libdecor_frame*,struct libdecor_configuration*,void*);+ void (* close)(struct libdecor_frame*,void*);+ void (* commit)(struct libdecor_frame*,void*);+ void (* dismiss_popup)(struct libdecor_frame*,const char*,void*);+ void (* reserved0)(void);+ void (* reserved1)(void);+ void (* reserved2)(void);+ void (* reserved3)(void);+ void (* reserved4)(void);+ void (* reserved5)(void);+ void (* reserved6)(void);+ void (* reserved7)(void);+ void (* reserved8)(void);+ void (* reserved9)(void);+};++typedef struct libdecor* (* PFN_libdecor_new)(struct wl_display*,const struct libdecor_interface*);+typedef void (* PFN_libdecor_unref)(struct libdecor*);+typedef int (* PFN_libdecor_get_fd)(struct libdecor*);+typedef int (* PFN_libdecor_dispatch)(struct libdecor*,int);+typedef struct libdecor_frame* (* PFN_libdecor_decorate)(struct libdecor*,struct wl_surface*,const struct libdecor_frame_interface*,void*);+typedef void (* PFN_libdecor_frame_unref)(struct libdecor_frame*);+typedef void (* PFN_libdecor_frame_set_app_id)(struct libdecor_frame*,const char*);+typedef void (* PFN_libdecor_frame_set_title)(struct libdecor_frame*,const char*);+typedef void (* PFN_libdecor_frame_set_minimized)(struct libdecor_frame*);+typedef void (* PFN_libdecor_frame_set_fullscreen)(struct libdecor_frame*,struct wl_output*);+typedef void (* PFN_libdecor_frame_unset_fullscreen)(struct libdecor_frame*);+typedef void (* PFN_libdecor_frame_map)(struct libdecor_frame*);+typedef void (* PFN_libdecor_frame_commit)(struct libdecor_frame*,struct libdecor_state*,struct libdecor_configuration*);+typedef void (* PFN_libdecor_frame_set_min_content_size)(struct libdecor_frame*,int,int);+typedef void (* PFN_libdecor_frame_set_max_content_size)(struct libdecor_frame*,int,int);+typedef void (* PFN_libdecor_frame_set_maximized)(struct libdecor_frame*);+typedef void (* PFN_libdecor_frame_unset_maximized)(struct libdecor_frame*);+typedef void (* PFN_libdecor_frame_set_capabilities)(struct libdecor_frame*,enum libdecor_capabilities);+typedef void (* PFN_libdecor_frame_unset_capabilities)(struct libdecor_frame*,enum libdecor_capabilities);+typedef void (* PFN_libdecor_frame_set_visibility)(struct libdecor_frame*,bool visible);+typedef struct xdg_toplevel* (* PFN_libdecor_frame_get_xdg_toplevel)(struct libdecor_frame*);+typedef bool (* PFN_libdecor_configuration_get_content_size)(struct libdecor_configuration*,struct libdecor_frame*,int*,int*);+typedef bool (* PFN_libdecor_configuration_get_window_state)(struct libdecor_configuration*,enum libdecor_window_state*);+typedef struct libdecor_state* (* PFN_libdecor_state_new)(int,int);+typedef void (* PFN_libdecor_state_free)(struct libdecor_state*);+#define libdecor_new _glfw.wl.libdecor.libdecor_new_+#define libdecor_unref _glfw.wl.libdecor.libdecor_unref_+#define libdecor_get_fd _glfw.wl.libdecor.libdecor_get_fd_+#define libdecor_dispatch _glfw.wl.libdecor.libdecor_dispatch_+#define libdecor_decorate _glfw.wl.libdecor.libdecor_decorate_+#define libdecor_frame_unref _glfw.wl.libdecor.libdecor_frame_unref_+#define libdecor_frame_set_app_id _glfw.wl.libdecor.libdecor_frame_set_app_id_+#define libdecor_frame_set_title _glfw.wl.libdecor.libdecor_frame_set_title_+#define libdecor_frame_set_minimized _glfw.wl.libdecor.libdecor_frame_set_minimized_+#define libdecor_frame_set_fullscreen _glfw.wl.libdecor.libdecor_frame_set_fullscreen_+#define libdecor_frame_unset_fullscreen _glfw.wl.libdecor.libdecor_frame_unset_fullscreen_+#define libdecor_frame_map _glfw.wl.libdecor.libdecor_frame_map_+#define libdecor_frame_commit _glfw.wl.libdecor.libdecor_frame_commit_+#define libdecor_frame_set_min_content_size _glfw.wl.libdecor.libdecor_frame_set_min_content_size_+#define libdecor_frame_set_max_content_size _glfw.wl.libdecor.libdecor_frame_set_max_content_size_+#define libdecor_frame_set_maximized _glfw.wl.libdecor.libdecor_frame_set_maximized_+#define libdecor_frame_unset_maximized _glfw.wl.libdecor.libdecor_frame_unset_maximized_+#define libdecor_frame_set_capabilities _glfw.wl.libdecor.libdecor_frame_set_capabilities_+#define libdecor_frame_unset_capabilities _glfw.wl.libdecor.libdecor_frame_unset_capabilities_+#define libdecor_frame_set_visibility _glfw.wl.libdecor.libdecor_frame_set_visibility_+#define libdecor_frame_get_xdg_toplevel _glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_+#define libdecor_configuration_get_content_size _glfw.wl.libdecor.libdecor_configuration_get_content_size_+#define libdecor_configuration_get_window_state _glfw.wl.libdecor.libdecor_configuration_get_window_state_+#define libdecor_state_new _glfw.wl.libdecor.libdecor_state_new_+#define libdecor_state_free _glfw.wl.libdecor.libdecor_state_free_++typedef struct _GLFWfallbackEdgeWayland+{ struct wl_surface* surface; struct wl_subsurface* subsurface; struct wp_viewport* viewport;-} _GLFWdecorationWayland;+} _GLFWfallbackEdgeWayland; typedef struct _GLFWofferWayland {@@ -221,17 +339,25 @@ GLFWbool text_uri_list; } _GLFWofferWayland; +typedef struct _GLFWscaleWayland+{+ struct wl_output* output;+ int32_t factor;+} _GLFWscaleWayland;+ // Wayland-specific per-window data // typedef struct _GLFWwindowWayland { int width, height;+ int fbWidth, fbHeight; GLFWbool visible; GLFWbool maximized; GLFWbool activated; GLFWbool fullscreen; GLFWbool hovered; GLFWbool transparent;+ GLFWbool scaleFramebuffer; struct wl_surface* surface; struct wl_callback* callback; @@ -254,30 +380,39 @@ uint32_t decorationMode; } xdg; + struct {+ struct libdecor_frame* frame;+ } libdecor;+ _GLFWcursor* currentCursor; double cursorPosX, cursorPosY; - char* title; char* appId; // We need to track the monitors the window spans on to calculate the // optimal scaling factor.- int scale;- _GLFWmonitor** monitors;- int monitorsCount;- int monitorsSize;+ int32_t bufferScale;+ _GLFWscaleWayland* outputScales;+ size_t outputScaleCount;+ size_t outputScaleSize; + struct wp_viewport* scalingViewport;+ uint32_t scalingNumerator;+ struct wp_fractional_scale_v1* fractionalScale;+ struct zwp_relative_pointer_v1* relativePointer; struct zwp_locked_pointer_v1* lockedPointer; struct zwp_confined_pointer_v1* confinedPointer; - struct zwp_idle_inhibitor_v1* idleInhibitor;+ struct zwp_idle_inhibitor_v1* idleInhibitor;+ struct xdg_activation_token_v1* activationToken; struct {- struct wl_buffer* buffer;- _GLFWdecorationWayland top, left, right, bottom;- _GLFWdecorationSideWayland focus;- } decorations;+ GLFWbool decorations;+ struct wl_buffer* buffer;+ _GLFWfallbackEdgeWayland top, left, right, bottom;+ struct wl_surface* focus;+ } fallback; } _GLFWwindowWayland; // Wayland-specific global data@@ -300,6 +435,8 @@ struct zwp_relative_pointer_manager_v1* relativePointerManager; struct zwp_pointer_constraints_v1* pointerConstraints; struct zwp_idle_inhibit_manager_v1* idleInhibitManager;+ struct xdg_activation_v1* activationManager;+ struct wp_fractional_scale_manager_v1* fractionalScaleManager; _GLFWofferWayland* offers; unsigned int offerCount;@@ -311,8 +448,7 @@ _GLFWwindow* dragFocus; uint32_t dragSerial; - int compositorVersion;- int seatVersion;+ const char* tag; struct wl_cursor_theme* cursorTheme; struct wl_cursor_theme* cursorThemeHiDPI;@@ -391,6 +527,8 @@ PFN_wl_proxy_marshal_constructor_versioned proxy_marshal_constructor_versioned; PFN_wl_proxy_get_user_data proxy_get_user_data; PFN_wl_proxy_set_user_data proxy_set_user_data;+ PFN_wl_proxy_get_tag proxy_get_tag;+ PFN_wl_proxy_set_tag proxy_set_tag; PFN_wl_proxy_get_version proxy_get_version; PFN_wl_proxy_marshal_flags proxy_marshal_flags; } client;@@ -411,6 +549,38 @@ PFN_wl_egl_window_destroy window_destroy; PFN_wl_egl_window_resize window_resize; } egl;++ struct {+ void* handle;+ struct libdecor* context;+ struct wl_callback* callback;+ GLFWbool ready;+ PFN_libdecor_new libdecor_new_;+ PFN_libdecor_unref libdecor_unref_;+ PFN_libdecor_get_fd libdecor_get_fd_;+ PFN_libdecor_dispatch libdecor_dispatch_;+ PFN_libdecor_decorate libdecor_decorate_;+ PFN_libdecor_frame_unref libdecor_frame_unref_;+ PFN_libdecor_frame_set_app_id libdecor_frame_set_app_id_;+ PFN_libdecor_frame_set_title libdecor_frame_set_title_;+ PFN_libdecor_frame_set_minimized libdecor_frame_set_minimized_;+ PFN_libdecor_frame_set_fullscreen libdecor_frame_set_fullscreen_;+ PFN_libdecor_frame_unset_fullscreen libdecor_frame_unset_fullscreen_;+ PFN_libdecor_frame_map libdecor_frame_map_;+ PFN_libdecor_frame_commit libdecor_frame_commit_;+ PFN_libdecor_frame_set_min_content_size libdecor_frame_set_min_content_size_;+ PFN_libdecor_frame_set_max_content_size libdecor_frame_set_max_content_size_;+ PFN_libdecor_frame_set_maximized libdecor_frame_set_maximized_;+ PFN_libdecor_frame_unset_maximized libdecor_frame_unset_maximized_;+ PFN_libdecor_frame_set_capabilities libdecor_frame_set_capabilities_;+ PFN_libdecor_frame_unset_capabilities libdecor_frame_unset_capabilities_;+ PFN_libdecor_frame_set_visibility libdecor_frame_set_visibility_;+ PFN_libdecor_frame_get_xdg_toplevel libdecor_frame_get_xdg_toplevel_;+ PFN_libdecor_configuration_get_content_size libdecor_configuration_get_content_size_;+ PFN_libdecor_configuration_get_window_state libdecor_configuration_get_window_state_;+ PFN_libdecor_state_new libdecor_state_new_;+ PFN_libdecor_state_free libdecor_state_free_;+ } libdecor; } _GLFWlibraryWayland; // Wayland-specific per-monitor data@@ -423,7 +593,7 @@ int x; int y;- int scale;+ int32_t scale; } _GLFWmonitorWayland; // Wayland-specific per-cursor data@@ -509,12 +679,12 @@ void _glfwGetMonitorContentScaleWayland(_GLFWmonitor* monitor, float* xscale, float* yscale); void _glfwGetMonitorWorkareaWayland(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height); GLFWvidmode* _glfwGetVideoModesWayland(_GLFWmonitor* monitor, int* count);-void _glfwGetVideoModeWayland(_GLFWmonitor* monitor, GLFWvidmode* mode);+GLFWbool _glfwGetVideoModeWayland(_GLFWmonitor* monitor, GLFWvidmode* mode); GLFWbool _glfwGetGammaRampWayland(_GLFWmonitor* monitor, GLFWgammaramp* ramp); void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); void _glfwAddOutputWayland(uint32_t name, uint32_t version);-void _glfwUpdateContentScaleWayland(_GLFWwindow* window);+void _glfwUpdateBufferScaleFromOutputsWayland(_GLFWwindow* window); void _glfwAddSeatListenerWayland(struct wl_seat* seat); void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);
raylib/src/external/glfw/src/wl_window.c view
@@ -1,2889 +1,3309 @@ //========================================================================-// GLFW 3.4 Wayland - www.glfw.org-//-------------------------------------------------------------------------// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>-//-// This software is provided 'as-is', without any express or implied-// warranty. In no event will the authors be held liable for any damages-// arising from the use of this software.-//-// Permission is granted to anyone to use this software for any purpose,-// including commercial applications, and to alter it and redistribute it-// freely, subject to the following restrictions:-//-// 1. The origin of this software must not be misrepresented; you must not-// claim that you wrote the original software. If you use this software-// in a product, an acknowledgment in the product documentation would-// be appreciated but is not required.-//-// 2. Altered source versions must be plainly marked as such, and must not-// be misrepresented as being the original software.-//-// 3. This notice may not be removed or altered from any source-// distribution.-//-//========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//========================================================================--#define _GNU_SOURCE--#include "internal.h"--#include <stdio.h>-#include <stdlib.h>-#include <errno.h>-#include <assert.h>-#include <unistd.h>-#include <string.h>-#include <fcntl.h>-#include <sys/mman.h>-#include <sys/timerfd.h>-#include <poll.h>--#include "wayland-client-protocol.h"-#include "wayland-xdg-shell-client-protocol.h"-#include "wayland-xdg-decoration-client-protocol.h"-#include "wayland-viewporter-client-protocol.h"-#include "wayland-relative-pointer-unstable-v1-client-protocol.h"-#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"-#include "wayland-idle-inhibit-unstable-v1-client-protocol.h"--#define GLFW_BORDER_SIZE 4-#define GLFW_CAPTION_HEIGHT 24--static int createTmpfileCloexec(char* tmpname)-{- int fd;-- fd = mkostemp(tmpname, O_CLOEXEC);- if (fd >= 0)- unlink(tmpname);-- return fd;-}--/*- * Create a new, unique, anonymous file of the given size, and- * return the file descriptor for it. The file descriptor is set- * CLOEXEC. The file is immediately suitable for mmap()'ing- * the given size at offset zero.- *- * The file should not have a permanent backing store like a disk,- * but may have if XDG_RUNTIME_DIR is not properly implemented in OS.- *- * The file name is deleted from the file system.- *- * The file is suitable for buffer sharing between processes by- * transmitting the file descriptor over Unix sockets using the- * SCM_RIGHTS methods.- *- * posix_fallocate() is used to guarantee that disk space is available- * for the file at the given size. If disk space is insufficient, errno- * is set to ENOSPC. If posix_fallocate() is not supported, program may- * receive SIGBUS on accessing mmap()'ed file contents instead.- */-static int createAnonymousFile(off_t size)-{- static const char template[] = "/glfw-shared-XXXXXX";- const char* path;- char* name;- int fd;- int ret;--#ifdef HAVE_MEMFD_CREATE- fd = memfd_create("glfw-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING);- if (fd >= 0)- {- // We can add this seal before calling posix_fallocate(), as the file- // is currently zero-sized anyway.- //- // There is also no need to check for the return value, we couldn’t do- // anything with it anyway.- fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);- }- else-#elif defined(SHM_ANON)- fd = shm_open(SHM_ANON, O_RDWR | O_CLOEXEC, 0600);- if (fd < 0)-#endif- {- path = getenv("XDG_RUNTIME_DIR");- if (!path)- {- errno = ENOENT;- return -1;- }-- name = _glfw_calloc(strlen(path) + sizeof(template), 1);- strcpy(name, path);- strcat(name, template);-- fd = createTmpfileCloexec(name);- _glfw_free(name);- if (fd < 0)- return -1;- }--#if defined(SHM_ANON)- // posix_fallocate does not work on SHM descriptors- ret = ftruncate(fd, size);-#else- ret = posix_fallocate(fd, 0, size);-#endif- if (ret != 0)- {- close(fd);- errno = ret;- return -1;- }- return fd;-}--static struct wl_buffer* createShmBuffer(const GLFWimage* image)-{- const int stride = image->width * 4;- const int length = image->width * image->height * 4;-- const int fd = createAnonymousFile(length);- if (fd < 0)- {- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to create buffer file of size %d: %s",- length, strerror(errno));- return NULL;- }-- void* data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);- if (data == MAP_FAILED)- {- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to map file: %s", strerror(errno));- close(fd);- return NULL;- }-- struct wl_shm_pool* pool = wl_shm_create_pool(_glfw.wl.shm, fd, length);-- close(fd);-- unsigned char* source = (unsigned char*) image->pixels;- unsigned char* target = data;- for (int i = 0; i < image->width * image->height; i++, source += 4)- {- unsigned int alpha = source[3];-- *target++ = (unsigned char) ((source[2] * alpha) / 255);- *target++ = (unsigned char) ((source[1] * alpha) / 255);- *target++ = (unsigned char) ((source[0] * alpha) / 255);- *target++ = (unsigned char) alpha;- }-- struct wl_buffer* buffer =- wl_shm_pool_create_buffer(pool, 0,- image->width,- image->height,- stride, WL_SHM_FORMAT_ARGB8888);- munmap(data, length);- wl_shm_pool_destroy(pool);-- return buffer;-}--static void createFallbackDecoration(_GLFWdecorationWayland* decoration,- struct wl_surface* parent,- struct wl_buffer* buffer,- int x, int y,- int width, int height)-{- decoration->surface = wl_compositor_create_surface(_glfw.wl.compositor);- decoration->subsurface =- wl_subcompositor_get_subsurface(_glfw.wl.subcompositor,- decoration->surface, parent);- wl_subsurface_set_position(decoration->subsurface, x, y);- decoration->viewport = wp_viewporter_get_viewport(_glfw.wl.viewporter,- decoration->surface);- wp_viewport_set_destination(decoration->viewport, width, height);- wl_surface_attach(decoration->surface, buffer, 0, 0);-- struct wl_region* region = wl_compositor_create_region(_glfw.wl.compositor);- wl_region_add(region, 0, 0, width, height);- wl_surface_set_opaque_region(decoration->surface, region);- wl_surface_commit(decoration->surface);- wl_region_destroy(region);-}--static void createFallbackDecorations(_GLFWwindow* window)-{- unsigned char data[] = { 224, 224, 224, 255 };- const GLFWimage image = { 1, 1, data };-- if (!_glfw.wl.viewporter)- return;-- if (!window->wl.decorations.buffer)- window->wl.decorations.buffer = createShmBuffer(&image);- if (!window->wl.decorations.buffer)- return;-- createFallbackDecoration(&window->wl.decorations.top, window->wl.surface,- window->wl.decorations.buffer,- 0, -GLFW_CAPTION_HEIGHT,- window->wl.width, GLFW_CAPTION_HEIGHT);- createFallbackDecoration(&window->wl.decorations.left, window->wl.surface,- window->wl.decorations.buffer,- -GLFW_BORDER_SIZE, -GLFW_CAPTION_HEIGHT,- GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT);- createFallbackDecoration(&window->wl.decorations.right, window->wl.surface,- window->wl.decorations.buffer,- window->wl.width, -GLFW_CAPTION_HEIGHT,- GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT);- createFallbackDecoration(&window->wl.decorations.bottom, window->wl.surface,- window->wl.decorations.buffer,- -GLFW_BORDER_SIZE, window->wl.height,- window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE);-}--static void destroyFallbackDecoration(_GLFWdecorationWayland* decoration)-{- if (decoration->subsurface)- wl_subsurface_destroy(decoration->subsurface);- if (decoration->surface)- wl_surface_destroy(decoration->surface);- if (decoration->viewport)- wp_viewport_destroy(decoration->viewport);- decoration->surface = NULL;- decoration->subsurface = NULL;- decoration->viewport = NULL;-}--static void destroyFallbackDecorations(_GLFWwindow* window)-{- destroyFallbackDecoration(&window->wl.decorations.top);- destroyFallbackDecoration(&window->wl.decorations.left);- destroyFallbackDecoration(&window->wl.decorations.right);- destroyFallbackDecoration(&window->wl.decorations.bottom);-}--static void xdgDecorationHandleConfigure(void* userData,- struct zxdg_toplevel_decoration_v1* decoration,- uint32_t mode)-{- _GLFWwindow* window = userData;-- window->wl.xdg.decorationMode = mode;-- if (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE)- {- if (window->decorated && !window->monitor)- createFallbackDecorations(window);- }- else- destroyFallbackDecorations(window);-}--static const struct zxdg_toplevel_decoration_v1_listener xdgDecorationListener =-{- xdgDecorationHandleConfigure,-};--// Makes the surface considered as XRGB instead of ARGB.-static void setContentAreaOpaque(_GLFWwindow* window)-{- struct wl_region* region;-- region = wl_compositor_create_region(_glfw.wl.compositor);- if (!region)- return;-- wl_region_add(region, 0, 0, window->wl.width, window->wl.height);- wl_surface_set_opaque_region(window->wl.surface, region);- wl_region_destroy(region);-}---static void resizeWindow(_GLFWwindow* window)-{- int scale = window->wl.scale;- int scaledWidth = window->wl.width * scale;- int scaledHeight = window->wl.height * scale;-- if (window->wl.egl.window)- wl_egl_window_resize(window->wl.egl.window, scaledWidth, scaledHeight, 0, 0);- if (!window->wl.transparent)- setContentAreaOpaque(window);- _glfwInputFramebufferSize(window, scaledWidth, scaledHeight);-- if (!window->wl.decorations.top.surface)- return;-- wp_viewport_set_destination(window->wl.decorations.top.viewport,- window->wl.width, GLFW_CAPTION_HEIGHT);- wl_surface_commit(window->wl.decorations.top.surface);-- wp_viewport_set_destination(window->wl.decorations.left.viewport,- GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT);- wl_surface_commit(window->wl.decorations.left.surface);-- wl_subsurface_set_position(window->wl.decorations.right.subsurface,- window->wl.width, -GLFW_CAPTION_HEIGHT);- wp_viewport_set_destination(window->wl.decorations.right.viewport,- GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT);- wl_surface_commit(window->wl.decorations.right.surface);-- wl_subsurface_set_position(window->wl.decorations.bottom.subsurface,- -GLFW_BORDER_SIZE, window->wl.height);- wp_viewport_set_destination(window->wl.decorations.bottom.viewport,- window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE);- wl_surface_commit(window->wl.decorations.bottom.surface);-}--void _glfwUpdateContentScaleWayland(_GLFWwindow* window)-{- if (_glfw.wl.compositorVersion < WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)- return;-- // Get the scale factor from the highest scale monitor.- int maxScale = 1;-- for (int i = 0; i < window->wl.monitorsCount; i++)- maxScale = _glfw_max(window->wl.monitors[i]->wl.scale, maxScale);-- // Only change the framebuffer size if the scale changed.- if (window->wl.scale != maxScale)- {- window->wl.scale = maxScale;- wl_surface_set_buffer_scale(window->wl.surface, maxScale);- _glfwInputWindowContentScale(window, maxScale, maxScale);- resizeWindow(window);- }-}--static void surfaceHandleEnter(void* userData,- struct wl_surface* surface,- struct wl_output* output)-{- _GLFWwindow* window = userData;- _GLFWmonitor* monitor = wl_output_get_user_data(output);-- if (window->wl.monitorsCount + 1 > window->wl.monitorsSize)- {- ++window->wl.monitorsSize;- window->wl.monitors =- _glfw_realloc(window->wl.monitors,- window->wl.monitorsSize * sizeof(_GLFWmonitor*));- }-- window->wl.monitors[window->wl.monitorsCount++] = monitor;-- _glfwUpdateContentScaleWayland(window);-}--static void surfaceHandleLeave(void* userData,- struct wl_surface* surface,- struct wl_output* output)-{- _GLFWwindow* window = userData;- _GLFWmonitor* monitor = wl_output_get_user_data(output);- GLFWbool found = GLFW_FALSE;-- for (int i = 0; i < window->wl.monitorsCount - 1; ++i)- {- if (monitor == window->wl.monitors[i])- found = GLFW_TRUE;- if (found)- window->wl.monitors[i] = window->wl.monitors[i + 1];- }- window->wl.monitors[--window->wl.monitorsCount] = NULL;-- _glfwUpdateContentScaleWayland(window);-}--static const struct wl_surface_listener surfaceListener =-{- surfaceHandleEnter,- surfaceHandleLeave-};--static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable)-{- if (enable && !window->wl.idleInhibitor && _glfw.wl.idleInhibitManager)- {- window->wl.idleInhibitor =- zwp_idle_inhibit_manager_v1_create_inhibitor(- _glfw.wl.idleInhibitManager, window->wl.surface);- if (!window->wl.idleInhibitor)- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to create idle inhibitor");- }- else if (!enable && window->wl.idleInhibitor)- {- zwp_idle_inhibitor_v1_destroy(window->wl.idleInhibitor);- window->wl.idleInhibitor = NULL;- }-}--// Make the specified window and its video mode active on its monitor-//-static void acquireMonitor(_GLFWwindow* window)-{- if (window->wl.xdg.toplevel)- {- xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel,- window->monitor->wl.output);- }-- setIdleInhibitor(window, GLFW_TRUE);-- if (window->wl.decorations.top.surface)- destroyFallbackDecorations(window);-}--// Remove the window and restore the original video mode-//-static void releaseMonitor(_GLFWwindow* window)-{- if (window->wl.xdg.toplevel)- xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);-- setIdleInhibitor(window, GLFW_FALSE);-- if (window->wl.xdg.decorationMode != ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE)- {- if (window->decorated)- createFallbackDecorations(window);- }-}--static void xdgToplevelHandleConfigure(void* userData,- struct xdg_toplevel* toplevel,- int32_t width,- int32_t height,- struct wl_array* states)-{- _GLFWwindow* window = userData;- uint32_t* state;-- window->wl.pending.activated = GLFW_FALSE;- window->wl.pending.maximized = GLFW_FALSE;- window->wl.pending.fullscreen = GLFW_FALSE;-- wl_array_for_each(state, states)- {- switch (*state)- {- case XDG_TOPLEVEL_STATE_MAXIMIZED:- window->wl.pending.maximized = GLFW_TRUE;- break;- case XDG_TOPLEVEL_STATE_FULLSCREEN:- window->wl.pending.fullscreen = GLFW_TRUE;- break;- case XDG_TOPLEVEL_STATE_RESIZING:- break;- case XDG_TOPLEVEL_STATE_ACTIVATED:- window->wl.pending.activated = GLFW_TRUE;- break;- }- }-- if (width && height)- {- if (window->wl.decorations.top.surface)- {- window->wl.pending.width = _glfw_max(0, width - GLFW_BORDER_SIZE * 2);- window->wl.pending.height =- _glfw_max(0, height - GLFW_BORDER_SIZE - GLFW_CAPTION_HEIGHT);- }- else- {- window->wl.pending.width = width;- window->wl.pending.height = height;- }- }- else- {- window->wl.pending.width = window->wl.width;- window->wl.pending.height = window->wl.height;- }-}--static void xdgToplevelHandleClose(void* userData,- struct xdg_toplevel* toplevel)-{- _GLFWwindow* window = userData;- _glfwInputWindowCloseRequest(window);-}--static const struct xdg_toplevel_listener xdgToplevelListener =-{- xdgToplevelHandleConfigure,- xdgToplevelHandleClose-};--static void xdgSurfaceHandleConfigure(void* userData,- struct xdg_surface* surface,- uint32_t serial)-{- _GLFWwindow* window = userData;-- xdg_surface_ack_configure(surface, serial);-- if (window->wl.activated != window->wl.pending.activated)- {- window->wl.activated = window->wl.pending.activated;- if (!window->wl.activated)- {- if (window->monitor && window->autoIconify)- xdg_toplevel_set_minimized(window->wl.xdg.toplevel);- }- }-- if (window->wl.maximized != window->wl.pending.maximized)- {- window->wl.maximized = window->wl.pending.maximized;- _glfwInputWindowMaximize(window, window->wl.maximized);- }-- window->wl.fullscreen = window->wl.pending.fullscreen;-- int width = window->wl.pending.width;- int height = window->wl.pending.height;-- if (!window->wl.maximized && !window->wl.fullscreen)- {- if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE)- {- const float aspectRatio = (float) width / (float) height;- const float targetRatio = (float) window->numer / (float) window->denom;- if (aspectRatio < targetRatio)- height = width / targetRatio;- else if (aspectRatio > targetRatio)- width = height * targetRatio;- }- }-- if (width != window->wl.width || height != window->wl.height)- {- window->wl.width = width;- window->wl.height = height;- resizeWindow(window);-- _glfwInputWindowSize(window, width, height);-- if (window->wl.visible)- _glfwInputWindowDamage(window);- }-- if (!window->wl.visible)- {- // Allow the window to be mapped only if it either has no XDG- // decorations or they have already received a configure event- if (!window->wl.xdg.decoration || window->wl.xdg.decorationMode)- {- window->wl.visible = GLFW_TRUE;- _glfwInputWindowDamage(window);- }- }-}--static const struct xdg_surface_listener xdgSurfaceListener =-{- xdgSurfaceHandleConfigure-};--static GLFWbool createShellObjects(_GLFWwindow* window)-{- window->wl.xdg.surface = xdg_wm_base_get_xdg_surface(_glfw.wl.wmBase,- window->wl.surface);- if (!window->wl.xdg.surface)- {- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to create xdg-surface for window");- return GLFW_FALSE;- }-- xdg_surface_add_listener(window->wl.xdg.surface, &xdgSurfaceListener, window);-- window->wl.xdg.toplevel = xdg_surface_get_toplevel(window->wl.xdg.surface);- if (!window->wl.xdg.toplevel)- {- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to create xdg-toplevel for window");- return GLFW_FALSE;- }-- xdg_toplevel_add_listener(window->wl.xdg.toplevel, &xdgToplevelListener, window);-- if (window->wl.appId)- xdg_toplevel_set_app_id(window->wl.xdg.toplevel, window->wl.appId);-- if (window->wl.title)- xdg_toplevel_set_title(window->wl.xdg.toplevel, window->wl.title);-- if (window->monitor)- {- xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel, window->monitor->wl.output);- setIdleInhibitor(window, GLFW_TRUE);- }- else- {- if (window->wl.maximized)- xdg_toplevel_set_maximized(window->wl.xdg.toplevel);-- setIdleInhibitor(window, GLFW_FALSE);-- if (_glfw.wl.decorationManager)- {- window->wl.xdg.decoration =- zxdg_decoration_manager_v1_get_toplevel_decoration(- _glfw.wl.decorationManager, window->wl.xdg.toplevel);- zxdg_toplevel_decoration_v1_add_listener(window->wl.xdg.decoration,- &xdgDecorationListener,- window);-- uint32_t mode;-- if (window->decorated)- mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE;- else- mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;-- zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode);- }- else- {- if (window->decorated)- createFallbackDecorations(window);- }- }-- if (window->minwidth != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE)- {- int minwidth = window->minwidth;- int minheight = window->minheight;-- if (window->wl.decorations.top.surface)- {- minwidth += GLFW_BORDER_SIZE * 2;- minheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE;- }-- xdg_toplevel_set_min_size(window->wl.xdg.toplevel, minwidth, minheight);- }-- if (window->maxwidth != GLFW_DONT_CARE && window->maxheight != GLFW_DONT_CARE)- {- int maxwidth = window->maxwidth;- int maxheight = window->maxheight;-- if (window->wl.decorations.top.surface)- {- maxwidth += GLFW_BORDER_SIZE * 2;- maxheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE;- }-- xdg_toplevel_set_max_size(window->wl.xdg.toplevel, maxwidth, maxheight);- }-- wl_surface_commit(window->wl.surface);- wl_display_roundtrip(_glfw.wl.display);-- return GLFW_TRUE;-}--static void destroyShellObjects(_GLFWwindow* window)-{- destroyFallbackDecorations(window);-- if (window->wl.xdg.decoration)- zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration);-- if (window->wl.xdg.toplevel)- xdg_toplevel_destroy(window->wl.xdg.toplevel);-- if (window->wl.xdg.surface)- xdg_surface_destroy(window->wl.xdg.surface);-- window->wl.xdg.decoration = NULL;- window->wl.xdg.decorationMode = 0;- window->wl.xdg.toplevel = NULL;- window->wl.xdg.surface = NULL;-}--static GLFWbool createNativeSurface(_GLFWwindow* window,- const _GLFWwndconfig* wndconfig,- const _GLFWfbconfig* fbconfig)-{- window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor);- if (!window->wl.surface)- {- _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Failed to create window surface");- return GLFW_FALSE;- }-- wl_surface_add_listener(window->wl.surface,- &surfaceListener,- window);-- wl_surface_set_user_data(window->wl.surface, window);-- window->wl.width = wndconfig->width;- window->wl.height = wndconfig->height;- window->wl.scale = 1;- window->wl.title = _glfw_strdup(wndconfig->title);- window->wl.appId = _glfw_strdup(wndconfig->wl.appId);-- window->wl.maximized = wndconfig->maximized;-- window->wl.transparent = fbconfig->transparent;- if (!window->wl.transparent)- setContentAreaOpaque(window);-- return GLFW_TRUE;-}--static void setCursorImage(_GLFWwindow* window,- _GLFWcursorWayland* cursorWayland)-{- struct itimerspec timer = {0};- struct wl_cursor* wlCursor = cursorWayland->cursor;- struct wl_cursor_image* image;- struct wl_buffer* buffer;- struct wl_surface* surface = _glfw.wl.cursorSurface;- int scale = 1;-- if (!wlCursor)- buffer = cursorWayland->buffer;- else- {- if (window->wl.scale > 1 && cursorWayland->cursorHiDPI)- {- wlCursor = cursorWayland->cursorHiDPI;- scale = 2;- }-- image = wlCursor->images[cursorWayland->currentImage];- buffer = wl_cursor_image_get_buffer(image);- if (!buffer)- return;-- timer.it_value.tv_sec = image->delay / 1000;- timer.it_value.tv_nsec = (image->delay % 1000) * 1000000;- timerfd_settime(_glfw.wl.cursorTimerfd, 0, &timer, NULL);-- cursorWayland->width = image->width;- cursorWayland->height = image->height;- cursorWayland->xhot = image->hotspot_x;- cursorWayland->yhot = image->hotspot_y;- }-- wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial,- surface,- cursorWayland->xhot / scale,- cursorWayland->yhot / scale);- wl_surface_set_buffer_scale(surface, scale);- wl_surface_attach(surface, buffer, 0, 0);- wl_surface_damage(surface, 0, 0,- cursorWayland->width, cursorWayland->height);- wl_surface_commit(surface);-}--static void incrementCursorImage(_GLFWwindow* window)-{- _GLFWcursor* cursor;-- if (!window || window->wl.decorations.focus != mainWindow)- return;-- cursor = window->wl.currentCursor;- if (cursor && cursor->wl.cursor)- {- cursor->wl.currentImage += 1;- cursor->wl.currentImage %= cursor->wl.cursor->image_count;- setCursorImage(window, &cursor->wl);- }-}--static GLFWbool flushDisplay(void)-{- while (wl_display_flush(_glfw.wl.display) == -1)- {- if (errno != EAGAIN)- return GLFW_FALSE;-- struct pollfd fd = { wl_display_get_fd(_glfw.wl.display), POLLOUT };-- while (poll(&fd, 1, -1) == -1)- {- if (errno != EINTR && errno != EAGAIN)- return GLFW_FALSE;- }- }-- return GLFW_TRUE;-}--static int translateKey(uint32_t scancode)-{- if (scancode < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0]))- return _glfw.wl.keycodes[scancode];-- return GLFW_KEY_UNKNOWN;-}--static xkb_keysym_t composeSymbol(xkb_keysym_t sym)-{- if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState)- return sym;- if (xkb_compose_state_feed(_glfw.wl.xkb.composeState, sym)- != XKB_COMPOSE_FEED_ACCEPTED)- return sym;- switch (xkb_compose_state_get_status(_glfw.wl.xkb.composeState))- {- case XKB_COMPOSE_COMPOSED:- return xkb_compose_state_get_one_sym(_glfw.wl.xkb.composeState);- case XKB_COMPOSE_COMPOSING:- case XKB_COMPOSE_CANCELLED:- return XKB_KEY_NoSymbol;- case XKB_COMPOSE_NOTHING:- default:- return sym;- }-}--static void inputText(_GLFWwindow* window, uint32_t scancode)-{- const xkb_keysym_t* keysyms;- const xkb_keycode_t keycode = scancode + 8;-- if (xkb_state_key_get_syms(_glfw.wl.xkb.state, keycode, &keysyms) == 1)- {- const xkb_keysym_t keysym = composeSymbol(keysyms[0]);- const uint32_t codepoint = _glfwKeySym2Unicode(keysym);- if (codepoint != GLFW_INVALID_CODEPOINT)- {- const int mods = _glfw.wl.xkb.modifiers;- const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));- _glfwInputChar(window, codepoint, mods, plain);- }- }-}--static void handleEvents(double* timeout)-{- GLFWbool event = GLFW_FALSE;- struct pollfd fds[] =- {- { wl_display_get_fd(_glfw.wl.display), POLLIN },- { _glfw.wl.keyRepeatTimerfd, POLLIN },- { _glfw.wl.cursorTimerfd, POLLIN },- };-- while (!event)- {- while (wl_display_prepare_read(_glfw.wl.display) != 0)- wl_display_dispatch_pending(_glfw.wl.display);-- // If an error other than EAGAIN happens, we have likely been disconnected- // from the Wayland session; try to handle that the best we can.- if (!flushDisplay())- {- wl_display_cancel_read(_glfw.wl.display);-- _GLFWwindow* window = _glfw.windowListHead;- while (window)- {- _glfwInputWindowCloseRequest(window);- window = window->next;- }-- return;- }-- if (!_glfwPollPOSIX(fds, 3, timeout))- {- wl_display_cancel_read(_glfw.wl.display);- return;- }-- if (fds[0].revents & POLLIN)- {- wl_display_read_events(_glfw.wl.display);- if (wl_display_dispatch_pending(_glfw.wl.display) > 0)- event = GLFW_TRUE;- }- else- wl_display_cancel_read(_glfw.wl.display);-- if (fds[1].revents & POLLIN)- {- uint64_t repeats;-- if (read(_glfw.wl.keyRepeatTimerfd, &repeats, sizeof(repeats)) == 8)- {- for (uint64_t i = 0; i < repeats; i++)- {- _glfwInputKey(_glfw.wl.keyboardFocus,- translateKey(_glfw.wl.keyRepeatScancode),- _glfw.wl.keyRepeatScancode,- GLFW_PRESS,- _glfw.wl.xkb.modifiers);- inputText(_glfw.wl.keyboardFocus, _glfw.wl.keyRepeatScancode);- }-- event = GLFW_TRUE;- }- }-- if (fds[2].revents & POLLIN)- {- uint64_t repeats;-- if (read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats)) == 8)- {- incrementCursorImage(_glfw.wl.pointerFocus);- event = GLFW_TRUE;- }- }- }-}--// Reads the specified data offer as the specified MIME type-//-static char* readDataOfferAsString(struct wl_data_offer* offer, const char* mimeType)-{- int fds[2];-- if (pipe2(fds, O_CLOEXEC) == -1)- {- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to create pipe for data offer: %s",- strerror(errno));- return NULL;- }-- wl_data_offer_receive(offer, mimeType, fds[1]);- flushDisplay();- close(fds[1]);-- char* string = NULL;- size_t size = 0;- size_t length = 0;-- for (;;)- {- const size_t readSize = 4096;- const size_t requiredSize = length + readSize + 1;- if (requiredSize > size)- {- char* longer = _glfw_realloc(string, requiredSize);- if (!longer)- {- _glfwInputError(GLFW_OUT_OF_MEMORY, NULL);- close(fds[0]);- return NULL;- }-- string = longer;- size = requiredSize;- }-- const ssize_t result = read(fds[0], string + length, readSize);- if (result == 0)- break;- else if (result == -1)- {- if (errno == EINTR)- continue;-- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to read from data offer pipe: %s",- strerror(errno));- close(fds[0]);- return NULL;- }-- length += result;- }-- close(fds[0]);-- string[length] = '\0';- return string;-}--static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,- _GLFWdecorationSideWayland* which)-{- _GLFWdecorationSideWayland focus;- _GLFWwindow* window = _glfw.windowListHead;- if (!which)- which = &focus;- while (window)- {- if (surface == window->wl.decorations.top.surface)- {- *which = topDecoration;- break;- }- if (surface == window->wl.decorations.left.surface)- {- *which = leftDecoration;- break;- }- if (surface == window->wl.decorations.right.surface)- {- *which = rightDecoration;- break;- }- if (surface == window->wl.decorations.bottom.surface)- {- *which = bottomDecoration;- break;- }- window = window->next;- }- return window;-}--static void pointerHandleEnter(void* userData,- struct wl_pointer* pointer,- uint32_t serial,- struct wl_surface* surface,- wl_fixed_t sx,- wl_fixed_t sy)-{- // Happens in the case we just destroyed the surface.- if (!surface)- return;-- _GLFWdecorationSideWayland focus = mainWindow;- _GLFWwindow* window = wl_surface_get_user_data(surface);- if (!window)- {- window = findWindowFromDecorationSurface(surface, &focus);- if (!window)- return;- }-- window->wl.decorations.focus = focus;- _glfw.wl.serial = serial;- _glfw.wl.pointerEnterSerial = serial;- _glfw.wl.pointerFocus = window;-- window->wl.hovered = GLFW_TRUE;-- _glfwSetCursorWayland(window, window->wl.currentCursor);- _glfwInputCursorEnter(window, GLFW_TRUE);-}--static void pointerHandleLeave(void* userData,- struct wl_pointer* pointer,- uint32_t serial,- struct wl_surface* surface)-{- _GLFWwindow* window = _glfw.wl.pointerFocus;-- if (!window)- return;-- window->wl.hovered = GLFW_FALSE;-- _glfw.wl.serial = serial;- _glfw.wl.pointerFocus = NULL;- _glfw.wl.cursorPreviousName = NULL;- _glfwInputCursorEnter(window, GLFW_FALSE);-}--static void setCursor(_GLFWwindow* window, const char* name)-{- struct wl_buffer* buffer;- struct wl_cursor* cursor;- struct wl_cursor_image* image;- struct wl_surface* surface = _glfw.wl.cursorSurface;- struct wl_cursor_theme* theme = _glfw.wl.cursorTheme;- int scale = 1;-- if (window->wl.scale > 1 && _glfw.wl.cursorThemeHiDPI)- {- // We only support up to scale=2 for now, since libwayland-cursor- // requires us to load a different theme for each size.- scale = 2;- theme = _glfw.wl.cursorThemeHiDPI;- }-- cursor = wl_cursor_theme_get_cursor(theme, name);- if (!cursor)- {- _glfwInputError(GLFW_CURSOR_UNAVAILABLE,- "Wayland: Standard cursor shape unavailable");- return;- }- // TODO: handle animated cursors too.- image = cursor->images[0];-- if (!image)- return;-- buffer = wl_cursor_image_get_buffer(image);- if (!buffer)- return;- wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial,- surface,- image->hotspot_x / scale,- image->hotspot_y / scale);- wl_surface_set_buffer_scale(surface, scale);- wl_surface_attach(surface, buffer, 0, 0);- wl_surface_damage(surface, 0, 0,- image->width, image->height);- wl_surface_commit(surface);- _glfw.wl.cursorPreviousName = name;-}--static void pointerHandleMotion(void* userData,- struct wl_pointer* pointer,- uint32_t time,- wl_fixed_t sx,- wl_fixed_t sy)-{- _GLFWwindow* window = _glfw.wl.pointerFocus;- const char* cursorName = NULL;- double x, y;-- if (!window)- return;-- if (window->cursorMode == GLFW_CURSOR_DISABLED)- return;- x = wl_fixed_to_double(sx);- y = wl_fixed_to_double(sy);- window->wl.cursorPosX = x;- window->wl.cursorPosY = y;-- switch (window->wl.decorations.focus)- {- case mainWindow:- _glfw.wl.cursorPreviousName = NULL;- _glfwInputCursorPos(window, x, y);- return;- case topDecoration:- if (y < GLFW_BORDER_SIZE)- cursorName = "n-resize";- else- cursorName = "left_ptr";- break;- case leftDecoration:- if (y < GLFW_BORDER_SIZE)- cursorName = "nw-resize";- else- cursorName = "w-resize";- break;- case rightDecoration:- if (y < GLFW_BORDER_SIZE)- cursorName = "ne-resize";- else- cursorName = "e-resize";- break;- case bottomDecoration:- if (x < GLFW_BORDER_SIZE)- cursorName = "sw-resize";- else if (x > window->wl.width + GLFW_BORDER_SIZE)- cursorName = "se-resize";- else- cursorName = "s-resize";- break;- default:- assert(0);- }- if (_glfw.wl.cursorPreviousName != cursorName)- setCursor(window, cursorName);-}--static void pointerHandleButton(void* userData,- struct wl_pointer* pointer,- uint32_t serial,- uint32_t time,- uint32_t button,- uint32_t state)-{- _GLFWwindow* window = _glfw.wl.pointerFocus;- int glfwButton;- uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;-- if (!window)- return;- if (button == BTN_LEFT)- {- switch (window->wl.decorations.focus)- {- case mainWindow:- break;- case topDecoration:- if (window->wl.cursorPosY < GLFW_BORDER_SIZE)- edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;- else- xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);- break;- case leftDecoration:- if (window->wl.cursorPosY < GLFW_BORDER_SIZE)- edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;- else- edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;- break;- case rightDecoration:- if (window->wl.cursorPosY < GLFW_BORDER_SIZE)- edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;- else- edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;- break;- case bottomDecoration:- if (window->wl.cursorPosX < GLFW_BORDER_SIZE)- edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;- else if (window->wl.cursorPosX > window->wl.width + GLFW_BORDER_SIZE)- edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;- else- edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;- break;- default:- assert(0);- }- if (edges != XDG_TOPLEVEL_RESIZE_EDGE_NONE)- {- xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat,- serial, edges);- return;- }- }- else if (button == BTN_RIGHT)- {- if (window->wl.decorations.focus != mainWindow && window->wl.xdg.toplevel)- {- xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,- _glfw.wl.seat, serial,- window->wl.cursorPosX,- window->wl.cursorPosY);- return;- }- }-- // Don’t pass the button to the user if it was related to a decoration.- if (window->wl.decorations.focus != mainWindow)- return;-- _glfw.wl.serial = serial;-- /* Makes left, right and middle 0, 1 and 2. Overall order follows evdev- * codes. */- glfwButton = button - BTN_LEFT;-- _glfwInputMouseClick(window,- glfwButton,- state == WL_POINTER_BUTTON_STATE_PRESSED- ? GLFW_PRESS- : GLFW_RELEASE,- _glfw.wl.xkb.modifiers);-}--static void pointerHandleAxis(void* userData,- struct wl_pointer* pointer,- uint32_t time,- uint32_t axis,- wl_fixed_t value)-{- _GLFWwindow* window = _glfw.wl.pointerFocus;- double x = 0.0, y = 0.0;- // Wayland scroll events are in pointer motion coordinate space (think two- // finger scroll). The factor 10 is commonly used to convert to "scroll- // step means 1.0.- const double scrollFactor = 1.0 / 10.0;-- if (!window)- return;-- assert(axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL ||- axis == WL_POINTER_AXIS_VERTICAL_SCROLL);-- if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)- x = -wl_fixed_to_double(value) * scrollFactor;- else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)- y = -wl_fixed_to_double(value) * scrollFactor;-- _glfwInputScroll(window, x, y);-}--static const struct wl_pointer_listener pointerListener =-{- pointerHandleEnter,- pointerHandleLeave,- pointerHandleMotion,- pointerHandleButton,- pointerHandleAxis,-};--static void keyboardHandleKeymap(void* userData,- struct wl_keyboard* keyboard,- uint32_t format,- int fd,- uint32_t size)-{- struct xkb_keymap* keymap;- struct xkb_state* state;- struct xkb_compose_table* composeTable;- struct xkb_compose_state* composeState;-- char* mapStr;- const char* locale;-- if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)- {- close(fd);- return;- }-- mapStr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);- if (mapStr == MAP_FAILED) {- close(fd);- return;- }-- keymap = xkb_keymap_new_from_string(_glfw.wl.xkb.context,- mapStr,- XKB_KEYMAP_FORMAT_TEXT_V1,- 0);- munmap(mapStr, size);- close(fd);-- if (!keymap)- {- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to compile keymap");- return;- }-- state = xkb_state_new(keymap);- if (!state)- {- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to create XKB state");- xkb_keymap_unref(keymap);- return;- }-- // Look up the preferred locale, falling back to "C" as default.- locale = getenv("LC_ALL");- if (!locale)- locale = getenv("LC_CTYPE");- if (!locale)- locale = getenv("LANG");- if (!locale)- locale = "C";-- composeTable =- xkb_compose_table_new_from_locale(_glfw.wl.xkb.context, locale,- XKB_COMPOSE_COMPILE_NO_FLAGS);- if (composeTable)- {- composeState =- xkb_compose_state_new(composeTable, XKB_COMPOSE_STATE_NO_FLAGS);- xkb_compose_table_unref(composeTable);- if (composeState)- _glfw.wl.xkb.composeState = composeState;- else- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to create XKB compose state");- }- else- {- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to create XKB compose table");- }-- xkb_keymap_unref(_glfw.wl.xkb.keymap);- xkb_state_unref(_glfw.wl.xkb.state);- _glfw.wl.xkb.keymap = keymap;- _glfw.wl.xkb.state = state;-- _glfw.wl.xkb.controlIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Control");- _glfw.wl.xkb.altIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod1");- _glfw.wl.xkb.shiftIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Shift");- _glfw.wl.xkb.superIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod4");- _glfw.wl.xkb.capsLockIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Lock");- _glfw.wl.xkb.numLockIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod2");-}--static void keyboardHandleEnter(void* userData,- struct wl_keyboard* keyboard,- uint32_t serial,- struct wl_surface* surface,- struct wl_array* keys)-{- // Happens in the case we just destroyed the surface.- if (!surface)- return;-- _GLFWwindow* window = wl_surface_get_user_data(surface);- if (!window)- {- window = findWindowFromDecorationSurface(surface, NULL);- if (!window)- return;- }-- _glfw.wl.serial = serial;- _glfw.wl.keyboardFocus = window;- _glfwInputWindowFocus(window, GLFW_TRUE);-}--static void keyboardHandleLeave(void* userData,- struct wl_keyboard* keyboard,- uint32_t serial,- struct wl_surface* surface)-{- _GLFWwindow* window = _glfw.wl.keyboardFocus;-- if (!window)- return;-- struct itimerspec timer = {0};- timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);-- _glfw.wl.serial = serial;- _glfw.wl.keyboardFocus = NULL;- _glfwInputWindowFocus(window, GLFW_FALSE);-}--static void keyboardHandleKey(void* userData,- struct wl_keyboard* keyboard,- uint32_t serial,- uint32_t time,- uint32_t scancode,- uint32_t state)-{- _GLFWwindow* window = _glfw.wl.keyboardFocus;- if (!window)- return;-- const int key = translateKey(scancode);- const int action =- state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE;-- _glfw.wl.serial = serial;-- struct itimerspec timer = {0};-- if (action == GLFW_PRESS)- {- const xkb_keycode_t keycode = scancode + 8;-- if (xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode) &&- _glfw.wl.keyRepeatRate > 0)- {- _glfw.wl.keyRepeatScancode = scancode;- if (_glfw.wl.keyRepeatRate > 1)- timer.it_interval.tv_nsec = 1000000000 / _glfw.wl.keyRepeatRate;- else- timer.it_interval.tv_sec = 1;-- timer.it_value.tv_sec = _glfw.wl.keyRepeatDelay / 1000;- timer.it_value.tv_nsec = (_glfw.wl.keyRepeatDelay % 1000) * 1000000;- }- }-- timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);-- _glfwInputKey(window, key, scancode, action, _glfw.wl.xkb.modifiers);-- if (action == GLFW_PRESS)- inputText(window, scancode);-}--static void keyboardHandleModifiers(void* userData,- struct wl_keyboard* keyboard,- uint32_t serial,- uint32_t modsDepressed,- uint32_t modsLatched,- uint32_t modsLocked,- uint32_t group)-{- _glfw.wl.serial = serial;-- if (!_glfw.wl.xkb.keymap)- return;-- xkb_state_update_mask(_glfw.wl.xkb.state,- modsDepressed,- modsLatched,- modsLocked,- 0,- 0,- group);-- _glfw.wl.xkb.modifiers = 0;-- struct- {- xkb_mod_index_t index;- unsigned int bit;- } modifiers[] =- {- { _glfw.wl.xkb.controlIndex, GLFW_MOD_CONTROL },- { _glfw.wl.xkb.altIndex, GLFW_MOD_ALT },- { _glfw.wl.xkb.shiftIndex, GLFW_MOD_SHIFT },- { _glfw.wl.xkb.superIndex, GLFW_MOD_SUPER },- { _glfw.wl.xkb.capsLockIndex, GLFW_MOD_CAPS_LOCK },- { _glfw.wl.xkb.numLockIndex, GLFW_MOD_NUM_LOCK }- };-- for (size_t i = 0; i < sizeof(modifiers) / sizeof(modifiers[0]); i++)- {- if (xkb_state_mod_index_is_active(_glfw.wl.xkb.state,- modifiers[i].index,- XKB_STATE_MODS_EFFECTIVE) == 1)- {- _glfw.wl.xkb.modifiers |= modifiers[i].bit;- }- }-}--#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION-static void keyboardHandleRepeatInfo(void* userData,- struct wl_keyboard* keyboard,- int32_t rate,- int32_t delay)-{- if (keyboard != _glfw.wl.keyboard)- return;-- _glfw.wl.keyRepeatRate = rate;- _glfw.wl.keyRepeatDelay = delay;-}-#endif--static const struct wl_keyboard_listener keyboardListener =-{- keyboardHandleKeymap,- keyboardHandleEnter,- keyboardHandleLeave,- keyboardHandleKey,- keyboardHandleModifiers,-#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION- keyboardHandleRepeatInfo,-#endif-};--static void seatHandleCapabilities(void* userData,- struct wl_seat* seat,- enum wl_seat_capability caps)-{- if ((caps & WL_SEAT_CAPABILITY_POINTER) && !_glfw.wl.pointer)- {- _glfw.wl.pointer = wl_seat_get_pointer(seat);- wl_pointer_add_listener(_glfw.wl.pointer, &pointerListener, NULL);- }- else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && _glfw.wl.pointer)- {- wl_pointer_destroy(_glfw.wl.pointer);- _glfw.wl.pointer = NULL;- }-- if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !_glfw.wl.keyboard)- {- _glfw.wl.keyboard = wl_seat_get_keyboard(seat);- wl_keyboard_add_listener(_glfw.wl.keyboard, &keyboardListener, NULL);- }- else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && _glfw.wl.keyboard)- {- wl_keyboard_destroy(_glfw.wl.keyboard);- _glfw.wl.keyboard = NULL;- }-}--static void seatHandleName(void* userData,- struct wl_seat* seat,- const char* name)-{-}--static const struct wl_seat_listener seatListener =-{- seatHandleCapabilities,- seatHandleName,-};--static void dataOfferHandleOffer(void* userData,- struct wl_data_offer* offer,- const char* mimeType)-{- for (unsigned int i = 0; i < _glfw.wl.offerCount; i++)- {- if (_glfw.wl.offers[i].offer == offer)- {- if (strcmp(mimeType, "text/plain;charset=utf-8") == 0)- _glfw.wl.offers[i].text_plain_utf8 = GLFW_TRUE;- else if (strcmp(mimeType, "text/uri-list") == 0)- _glfw.wl.offers[i].text_uri_list = GLFW_TRUE;-- break;- }- }-}--static const struct wl_data_offer_listener dataOfferListener =-{- dataOfferHandleOffer-};--static void dataDeviceHandleDataOffer(void* userData,- struct wl_data_device* device,- struct wl_data_offer* offer)-{- _GLFWofferWayland* offers =- _glfw_realloc(_glfw.wl.offers, _glfw.wl.offerCount + 1);- if (!offers)- {- _glfwInputError(GLFW_OUT_OF_MEMORY, NULL);- return;- }-- _glfw.wl.offers = offers;- _glfw.wl.offerCount++;-- _glfw.wl.offers[_glfw.wl.offerCount - 1] = (_GLFWofferWayland) { offer };- wl_data_offer_add_listener(offer, &dataOfferListener, NULL);-}--static void dataDeviceHandleEnter(void* userData,- struct wl_data_device* device,- uint32_t serial,- struct wl_surface* surface,- wl_fixed_t x,- wl_fixed_t y,- struct wl_data_offer* offer)-{- if (_glfw.wl.dragOffer)- {- wl_data_offer_destroy(_glfw.wl.dragOffer);- _glfw.wl.dragOffer = NULL;- _glfw.wl.dragFocus = NULL;- }-- for (unsigned int i = 0; i < _glfw.wl.offerCount; i++)- {- if (_glfw.wl.offers[i].offer == offer)- {- _GLFWwindow* window = NULL;-- if (surface)- window = wl_surface_get_user_data(surface);-- if (window && _glfw.wl.offers[i].text_uri_list)- {- _glfw.wl.dragOffer = offer;- _glfw.wl.dragFocus = window;- _glfw.wl.dragSerial = serial;- }-- _glfw.wl.offers[i] = _glfw.wl.offers[_glfw.wl.offerCount - 1];- _glfw.wl.offerCount--;- break;- }- }-- if (_glfw.wl.dragOffer)- wl_data_offer_accept(offer, serial, "text/uri-list");- else- {- wl_data_offer_accept(offer, serial, NULL);- wl_data_offer_destroy(offer);- }-}--static void dataDeviceHandleLeave(void* userData,- struct wl_data_device* device)-{- if (_glfw.wl.dragOffer)- {- wl_data_offer_destroy(_glfw.wl.dragOffer);- _glfw.wl.dragOffer = NULL;- _glfw.wl.dragFocus = NULL;- }-}--static void dataDeviceHandleMotion(void* userData,- struct wl_data_device* device,- uint32_t time,- wl_fixed_t x,- wl_fixed_t y)-{-}--static void dataDeviceHandleDrop(void* userData,- struct wl_data_device* device)-{- if (!_glfw.wl.dragOffer)- return;-- char* string = readDataOfferAsString(_glfw.wl.dragOffer, "text/uri-list");- if (string)- {- int count;- char** paths = _glfwParseUriList(string, &count);- if (paths)- _glfwInputDrop(_glfw.wl.dragFocus, count, (const char**) paths);-- for (int i = 0; i < count; i++)- _glfw_free(paths[i]);-- _glfw_free(paths);- }-- _glfw_free(string);-}--static void dataDeviceHandleSelection(void* userData,- struct wl_data_device* device,- struct wl_data_offer* offer)-{- if (_glfw.wl.selectionOffer)- {- wl_data_offer_destroy(_glfw.wl.selectionOffer);- _glfw.wl.selectionOffer = NULL;- }-- for (unsigned int i = 0; i < _glfw.wl.offerCount; i++)- {- if (_glfw.wl.offers[i].offer == offer)- {- if (_glfw.wl.offers[i].text_plain_utf8)- _glfw.wl.selectionOffer = offer;- else- wl_data_offer_destroy(offer);-- _glfw.wl.offers[i] = _glfw.wl.offers[_glfw.wl.offerCount - 1];- _glfw.wl.offerCount--;- break;- }- }-}--const struct wl_data_device_listener dataDeviceListener =-{- dataDeviceHandleDataOffer,- dataDeviceHandleEnter,- dataDeviceHandleLeave,- dataDeviceHandleMotion,- dataDeviceHandleDrop,- dataDeviceHandleSelection,-};--void _glfwAddSeatListenerWayland(struct wl_seat* seat)-{- wl_seat_add_listener(seat, &seatListener, NULL);-}--void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device)-{- wl_data_device_add_listener(device, &dataDeviceListener, NULL);-}---//////////////////////////////////////////////////////////////////////////-////// GLFW platform API //////-//////////////////////////////////////////////////////////////////////////--GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window,- const _GLFWwndconfig* wndconfig,- const _GLFWctxconfig* ctxconfig,- const _GLFWfbconfig* fbconfig)-{- if (!createNativeSurface(window, wndconfig, fbconfig))- return GLFW_FALSE;-- if (ctxconfig->client != GLFW_NO_API)- {- if (ctxconfig->source == GLFW_EGL_CONTEXT_API ||- ctxconfig->source == GLFW_NATIVE_CONTEXT_API)- {- window->wl.egl.window = wl_egl_window_create(window->wl.surface,- wndconfig->width,- wndconfig->height);- if (!window->wl.egl.window)- {- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to create EGL window");- return GLFW_FALSE;- }-- if (!_glfwInitEGL())- return GLFW_FALSE;- if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))- return GLFW_FALSE;- }- else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)- {- if (!_glfwInitOSMesa())- return GLFW_FALSE;- if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))- return GLFW_FALSE;- }-- if (!_glfwRefreshContextAttribs(window, ctxconfig))- return GLFW_FALSE;- }-- if (wndconfig->mousePassthrough)- _glfwSetWindowMousePassthroughWayland(window, GLFW_TRUE);-- if (window->monitor || wndconfig->visible)- {- if (!createShellObjects(window))- return GLFW_FALSE;- }-- return GLFW_TRUE;-}--void _glfwDestroyWindowWayland(_GLFWwindow* window)-{- if (window == _glfw.wl.pointerFocus)- _glfw.wl.pointerFocus = NULL;-- if (window == _glfw.wl.keyboardFocus)- _glfw.wl.keyboardFocus = NULL;-- if (window->wl.idleInhibitor)- zwp_idle_inhibitor_v1_destroy(window->wl.idleInhibitor);-- if (window->wl.relativePointer)- zwp_relative_pointer_v1_destroy(window->wl.relativePointer);-- if (window->wl.lockedPointer)- zwp_locked_pointer_v1_destroy(window->wl.lockedPointer);-- if (window->wl.confinedPointer)- zwp_confined_pointer_v1_destroy(window->wl.confinedPointer);-- if (window->context.destroy)- window->context.destroy(window);-- destroyShellObjects(window);-- if (window->wl.decorations.buffer)- wl_buffer_destroy(window->wl.decorations.buffer);-- if (window->wl.egl.window)- wl_egl_window_destroy(window->wl.egl.window);-- if (window->wl.surface)- wl_surface_destroy(window->wl.surface);-- _glfw_free(window->wl.title);- _glfw_free(window->wl.appId);- _glfw_free(window->wl.monitors);-}--void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title)-{- char* copy = _glfw_strdup(title);- _glfw_free(window->wl.title);- window->wl.title = copy;-- if (window->wl.xdg.toplevel)- xdg_toplevel_set_title(window->wl.xdg.toplevel, title);-}--void _glfwSetWindowIconWayland(_GLFWwindow* window,- int count, const GLFWimage* images)-{- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,- "Wayland: The platform does not support setting the window icon");-}--void _glfwGetWindowPosWayland(_GLFWwindow* window, int* xpos, int* ypos)-{- // A Wayland client is not aware of its position, so just warn and leave it- // as (0, 0)-- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,- "Wayland: The platform does not provide the window position");-}--void _glfwSetWindowPosWayland(_GLFWwindow* window, int xpos, int ypos)-{- // A Wayland client can not set its position, so just warn-- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,- "Wayland: The platform does not support setting the window position");-}--void _glfwGetWindowSizeWayland(_GLFWwindow* window, int* width, int* height)-{- if (width)- *width = window->wl.width;- if (height)- *height = window->wl.height;-}--void _glfwSetWindowSizeWayland(_GLFWwindow* window, int width, int height)-{- if (window->monitor)- {- // Video mode setting is not available on Wayland- }- else- {- window->wl.width = width;- window->wl.height = height;- resizeWindow(window);- }-}--void _glfwSetWindowSizeLimitsWayland(_GLFWwindow* window,- int minwidth, int minheight,- int maxwidth, int maxheight)-{- if (window->wl.xdg.toplevel)- {- if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE)- minwidth = minheight = 0;- else- {- if (window->wl.decorations.top.surface)- {- minwidth += GLFW_BORDER_SIZE * 2;- minheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE;- }- }-- if (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE)- maxwidth = maxheight = 0;- else- {- if (window->wl.decorations.top.surface)- {- maxwidth += GLFW_BORDER_SIZE * 2;- maxheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE;- }- }-- xdg_toplevel_set_min_size(window->wl.xdg.toplevel, minwidth, minheight);- xdg_toplevel_set_max_size(window->wl.xdg.toplevel, maxwidth, maxheight);- wl_surface_commit(window->wl.surface);- }-}--void _glfwSetWindowAspectRatioWayland(_GLFWwindow* window, int numer, int denom)-{- if (window->wl.maximized || window->wl.fullscreen)- return;-- if (numer != GLFW_DONT_CARE && denom != GLFW_DONT_CARE)- {- const float aspectRatio = (float) window->wl.width / (float) window->wl.height;- const float targetRatio = (float) numer / (float) denom;- if (aspectRatio < targetRatio)- window->wl.height = window->wl.width / targetRatio;- else if (aspectRatio > targetRatio)- window->wl.width = window->wl.height * targetRatio;-- resizeWindow(window);- }-}--void _glfwGetFramebufferSizeWayland(_GLFWwindow* window, int* width, int* height)-{- _glfwGetWindowSizeWayland(window, width, height);- if (width)- *width *= window->wl.scale;- if (height)- *height *= window->wl.scale;-}--void _glfwGetWindowFrameSizeWayland(_GLFWwindow* window,- int* left, int* top,- int* right, int* bottom)-{- if (window->decorated && !window->monitor && window->wl.decorations.top.surface)- {- if (top)- *top = GLFW_CAPTION_HEIGHT;- if (left)- *left = GLFW_BORDER_SIZE;- if (right)- *right = GLFW_BORDER_SIZE;- if (bottom)- *bottom = GLFW_BORDER_SIZE;- }-}--void _glfwGetWindowContentScaleWayland(_GLFWwindow* window,- float* xscale, float* yscale)-{- if (xscale)- *xscale = (float) window->wl.scale;- if (yscale)- *yscale = (float) window->wl.scale;-}--void _glfwIconifyWindowWayland(_GLFWwindow* window)-{- if (window->wl.xdg.toplevel)- xdg_toplevel_set_minimized(window->wl.xdg.toplevel);-}--void _glfwRestoreWindowWayland(_GLFWwindow* window)-{- if (window->monitor)- {- // There is no way to unset minimized, or even to know if we are- // minimized, so there is nothing to do in this case.- }- else- {- // We assume we are not minimized and act only on maximization-- if (window->wl.maximized)- {- if (window->wl.xdg.toplevel)- xdg_toplevel_unset_maximized(window->wl.xdg.toplevel);- else- window->wl.maximized = GLFW_FALSE;- }- }-}--void _glfwMaximizeWindowWayland(_GLFWwindow* window)-{- if (window->wl.xdg.toplevel)- xdg_toplevel_set_maximized(window->wl.xdg.toplevel);- else- window->wl.maximized = GLFW_TRUE;-}--void _glfwShowWindowWayland(_GLFWwindow* window)-{- if (!window->wl.xdg.toplevel)- {- // NOTE: The XDG surface and role are created here so command-line applications- // with off-screen windows do not appear in for example the Unity dock- createShellObjects(window);- }-}--void _glfwHideWindowWayland(_GLFWwindow* window)-{- if (window->wl.visible)- {- window->wl.visible = GLFW_FALSE;- destroyShellObjects(window);-- wl_surface_attach(window->wl.surface, NULL, 0, 0);- wl_surface_commit(window->wl.surface);- }-}--void _glfwRequestWindowAttentionWayland(_GLFWwindow* window)-{- // TODO- _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,- "Wayland: Window attention request not implemented yet");-}--void _glfwFocusWindowWayland(_GLFWwindow* window)-{- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,- "Wayland: The platform does not support setting the input focus");-}--void _glfwSetWindowMonitorWayland(_GLFWwindow* window,- _GLFWmonitor* monitor,- int xpos, int ypos,- int width, int height,- int refreshRate)-{- if (window->monitor == monitor)- {- if (!monitor)- _glfwSetWindowSizeWayland(window, width, height);-- return;- }-- if (window->monitor)- releaseMonitor(window);-- _glfwInputWindowMonitor(window, monitor);-- if (window->monitor)- acquireMonitor(window);- else- _glfwSetWindowSizeWayland(window, width, height);-}--GLFWbool _glfwWindowFocusedWayland(_GLFWwindow* window)-{- return _glfw.wl.keyboardFocus == window;-}--GLFWbool _glfwWindowIconifiedWayland(_GLFWwindow* window)-{- // xdg-shell doesn’t give any way to request whether a surface is- // iconified.- return GLFW_FALSE;-}--GLFWbool _glfwWindowVisibleWayland(_GLFWwindow* window)-{- return window->wl.visible;-}--GLFWbool _glfwWindowMaximizedWayland(_GLFWwindow* window)-{- return window->wl.maximized;-}--GLFWbool _glfwWindowHoveredWayland(_GLFWwindow* window)-{- return window->wl.hovered;-}--GLFWbool _glfwFramebufferTransparentWayland(_GLFWwindow* window)-{- return window->wl.transparent;-}--void _glfwSetWindowResizableWayland(_GLFWwindow* window, GLFWbool enabled)-{- // TODO- _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,- "Wayland: Window attribute setting not implemented yet");-}--void _glfwSetWindowDecoratedWayland(_GLFWwindow* window, GLFWbool enabled)-{- if (window->wl.xdg.decoration)- {- uint32_t mode;-- if (enabled)- mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE;- else- mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;-- zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode);- }- else- {- if (enabled)- createFallbackDecorations(window);- else- destroyFallbackDecorations(window);- }-}--void _glfwSetWindowFloatingWayland(_GLFWwindow* window, GLFWbool enabled)-{- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,- "Wayland: Platform does not support making a window floating");-}--void _glfwSetWindowMousePassthroughWayland(_GLFWwindow* window, GLFWbool enabled)-{- if (enabled)- {- struct wl_region* region = wl_compositor_create_region(_glfw.wl.compositor);- wl_surface_set_input_region(window->wl.surface, region);- wl_region_destroy(region);- }- else- wl_surface_set_input_region(window->wl.surface, 0);-}--float _glfwGetWindowOpacityWayland(_GLFWwindow* window)-{- return 1.f;-}--void _glfwSetWindowOpacityWayland(_GLFWwindow* window, float opacity)-{- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,- "Wayland: The platform does not support setting the window opacity");-}--void _glfwSetRawMouseMotionWayland(_GLFWwindow* window, GLFWbool enabled)-{- // This is handled in relativePointerHandleRelativeMotion-}--GLFWbool _glfwRawMouseMotionSupportedWayland(void)-{- return GLFW_TRUE;-}--void _glfwPollEventsWayland(void)-{- double timeout = 0.0;- handleEvents(&timeout);-}--void _glfwWaitEventsWayland(void)-{- handleEvents(NULL);-}--void _glfwWaitEventsTimeoutWayland(double timeout)-{- handleEvents(&timeout);-}--void _glfwPostEmptyEventWayland(void)-{- wl_display_sync(_glfw.wl.display);- flushDisplay();-}--void _glfwGetCursorPosWayland(_GLFWwindow* window, double* xpos, double* ypos)-{- if (xpos)- *xpos = window->wl.cursorPosX;- if (ypos)- *ypos = window->wl.cursorPosY;-}--void _glfwSetCursorPosWayland(_GLFWwindow* window, double x, double y)-{- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,- "Wayland: The platform does not support setting the cursor position");-}--void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode)-{- _glfwSetCursorWayland(window, window->wl.currentCursor);-}--const char* _glfwGetScancodeNameWayland(int scancode)-{- if (scancode < 0 || scancode > 255 ||- _glfw.wl.keycodes[scancode] == GLFW_KEY_UNKNOWN)- {- _glfwInputError(GLFW_INVALID_VALUE,- "Wayland: Invalid scancode %i",- scancode);- return NULL;- }-- const int key = _glfw.wl.keycodes[scancode];- const xkb_keycode_t keycode = scancode + 8;- const xkb_layout_index_t layout =- xkb_state_key_get_layout(_glfw.wl.xkb.state, keycode);- if (layout == XKB_LAYOUT_INVALID)- {- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to retrieve layout for key name");- return NULL;- }-- const xkb_keysym_t* keysyms = NULL;- xkb_keymap_key_get_syms_by_level(_glfw.wl.xkb.keymap,- keycode,- layout,- 0,- &keysyms);- if (keysyms == NULL)- {- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to retrieve keysym for key name");- return NULL;- }-- const uint32_t codepoint = _glfwKeySym2Unicode(keysyms[0]);- if (codepoint == GLFW_INVALID_CODEPOINT)- {- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to retrieve codepoint for key name");- return NULL;- }-- const size_t count = _glfwEncodeUTF8(_glfw.wl.keynames[key], codepoint);- if (count == 0)- {- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to encode codepoint for key name");- return NULL;- }-- _glfw.wl.keynames[key][count] = '\0';- return _glfw.wl.keynames[key];-}--int _glfwGetKeyScancodeWayland(int key)-{- return _glfw.wl.scancodes[key];-}--GLFWbool _glfwCreateCursorWayland(_GLFWcursor* cursor,- const GLFWimage* image,- int xhot, int yhot)-{- cursor->wl.buffer = createShmBuffer(image);- if (!cursor->wl.buffer)- return GLFW_FALSE;-- cursor->wl.width = image->width;- cursor->wl.height = image->height;- cursor->wl.xhot = xhot;- cursor->wl.yhot = yhot;- return GLFW_TRUE;-}--GLFWbool _glfwCreateStandardCursorWayland(_GLFWcursor* cursor, int shape)-{- const char* name = NULL;-- // Try the XDG names first- switch (shape)- {- case GLFW_ARROW_CURSOR:- name = "default";- break;- case GLFW_IBEAM_CURSOR:- name = "text";- break;- case GLFW_CROSSHAIR_CURSOR:- name = "crosshair";- break;- case GLFW_POINTING_HAND_CURSOR:- name = "pointer";- break;- case GLFW_RESIZE_EW_CURSOR:- name = "ew-resize";- break;- case GLFW_RESIZE_NS_CURSOR:- name = "ns-resize";- break;- case GLFW_RESIZE_NWSE_CURSOR:- name = "nwse-resize";- break;- case GLFW_RESIZE_NESW_CURSOR:- name = "nesw-resize";- break;- case GLFW_RESIZE_ALL_CURSOR:- name = "all-scroll";- break;- case GLFW_NOT_ALLOWED_CURSOR:- name = "not-allowed";- break;- }-- cursor->wl.cursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, name);-- if (_glfw.wl.cursorThemeHiDPI)- {- cursor->wl.cursorHiDPI =- wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI, name);- }-- if (!cursor->wl.cursor)- {- // Fall back to the core X11 names- switch (shape)- {- case GLFW_ARROW_CURSOR:- name = "left_ptr";- break;- case GLFW_IBEAM_CURSOR:- name = "xterm";- break;- case GLFW_CROSSHAIR_CURSOR:- name = "crosshair";- break;- case GLFW_POINTING_HAND_CURSOR:- name = "hand2";- break;- case GLFW_RESIZE_EW_CURSOR:- name = "sb_h_double_arrow";- break;- case GLFW_RESIZE_NS_CURSOR:- name = "sb_v_double_arrow";- break;- case GLFW_RESIZE_ALL_CURSOR:- name = "fleur";- break;- default:- _glfwInputError(GLFW_CURSOR_UNAVAILABLE,- "Wayland: Standard cursor shape unavailable");- return GLFW_FALSE;- }-- cursor->wl.cursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, name);- if (!cursor->wl.cursor)- {- _glfwInputError(GLFW_CURSOR_UNAVAILABLE,- "Wayland: Failed to create standard cursor \"%s\"",- name);- return GLFW_FALSE;- }-- if (_glfw.wl.cursorThemeHiDPI)- {- if (!cursor->wl.cursorHiDPI)- {- cursor->wl.cursorHiDPI =- wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI, name);- }- }- }-- return GLFW_TRUE;-}--void _glfwDestroyCursorWayland(_GLFWcursor* cursor)-{- // If it's a standard cursor we don't need to do anything here- if (cursor->wl.cursor)- return;-- if (cursor->wl.buffer)- wl_buffer_destroy(cursor->wl.buffer);-}--static void relativePointerHandleRelativeMotion(void* userData,- struct zwp_relative_pointer_v1* pointer,- uint32_t timeHi,- uint32_t timeLo,- wl_fixed_t dx,- wl_fixed_t dy,- wl_fixed_t dxUnaccel,- wl_fixed_t dyUnaccel)-{- _GLFWwindow* window = userData;- double xpos = window->virtualCursorPosX;- double ypos = window->virtualCursorPosY;-- if (window->cursorMode != GLFW_CURSOR_DISABLED)- return;-- if (window->rawMouseMotion)- {- xpos += wl_fixed_to_double(dxUnaccel);- ypos += wl_fixed_to_double(dyUnaccel);- }- else- {- xpos += wl_fixed_to_double(dx);- ypos += wl_fixed_to_double(dy);- }-- _glfwInputCursorPos(window, xpos, ypos);-}--static const struct zwp_relative_pointer_v1_listener relativePointerListener =-{- relativePointerHandleRelativeMotion-};--static void lockedPointerHandleLocked(void* userData,- struct zwp_locked_pointer_v1* lockedPointer)-{-}--static void lockedPointerHandleUnlocked(void* userData,- struct zwp_locked_pointer_v1* lockedPointer)-{-}--static const struct zwp_locked_pointer_v1_listener lockedPointerListener =-{- lockedPointerHandleLocked,- lockedPointerHandleUnlocked-};--static void lockPointer(_GLFWwindow* window)-{- if (!_glfw.wl.relativePointerManager)- {- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,- "Wayland: The compositor does not support pointer locking");- return;- }-- window->wl.relativePointer =- zwp_relative_pointer_manager_v1_get_relative_pointer(- _glfw.wl.relativePointerManager,- _glfw.wl.pointer);- zwp_relative_pointer_v1_add_listener(window->wl.relativePointer,- &relativePointerListener,- window);-- window->wl.lockedPointer =- zwp_pointer_constraints_v1_lock_pointer(- _glfw.wl.pointerConstraints,- window->wl.surface,- _glfw.wl.pointer,- NULL,- ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);- zwp_locked_pointer_v1_add_listener(window->wl.lockedPointer,- &lockedPointerListener,- window);-}--static void unlockPointer(_GLFWwindow* window)-{- zwp_relative_pointer_v1_destroy(window->wl.relativePointer);- window->wl.relativePointer = NULL;-- zwp_locked_pointer_v1_destroy(window->wl.lockedPointer);- window->wl.lockedPointer = NULL;-}--static void confinedPointerHandleConfined(void* userData,- struct zwp_confined_pointer_v1* confinedPointer)-{-}--static void confinedPointerHandleUnconfined(void* userData,- struct zwp_confined_pointer_v1* confinedPointer)-{-}--static const struct zwp_confined_pointer_v1_listener confinedPointerListener =-{- confinedPointerHandleConfined,- confinedPointerHandleUnconfined-};--static void confinePointer(_GLFWwindow* window)-{- window->wl.confinedPointer =- zwp_pointer_constraints_v1_confine_pointer(- _glfw.wl.pointerConstraints,- window->wl.surface,- _glfw.wl.pointer,- NULL,- ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);-- zwp_confined_pointer_v1_add_listener(window->wl.confinedPointer,- &confinedPointerListener,- window);-}--static void unconfinePointer(_GLFWwindow* window)-{- zwp_confined_pointer_v1_destroy(window->wl.confinedPointer);- window->wl.confinedPointer = NULL;-}--void _glfwSetCursorWayland(_GLFWwindow* window, _GLFWcursor* cursor)-{- if (!_glfw.wl.pointer)- return;-- window->wl.currentCursor = cursor;-- // If we're not in the correct window just save the cursor- // the next time the pointer enters the window the cursor will change- if (window != _glfw.wl.pointerFocus || window->wl.decorations.focus != mainWindow)- return;-- // Update pointer lock to match cursor mode- if (window->cursorMode == GLFW_CURSOR_DISABLED)- {- if (window->wl.confinedPointer)- unconfinePointer(window);- if (!window->wl.lockedPointer)- lockPointer(window);- }- else if (window->cursorMode == GLFW_CURSOR_CAPTURED)- {- if (window->wl.lockedPointer)- unlockPointer(window);- if (!window->wl.confinedPointer)- confinePointer(window);- }- else if (window->cursorMode == GLFW_CURSOR_NORMAL ||- window->cursorMode == GLFW_CURSOR_HIDDEN)- {- if (window->wl.lockedPointer)- unlockPointer(window);- else if (window->wl.confinedPointer)- unconfinePointer(window);- }-- if (window->cursorMode == GLFW_CURSOR_NORMAL ||- window->cursorMode == GLFW_CURSOR_CAPTURED)- {- if (cursor)- setCursorImage(window, &cursor->wl);- else- {- struct wl_cursor* defaultCursor =- wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, "left_ptr");- if (!defaultCursor)- {- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Standard cursor not found");- return;- }-- struct wl_cursor* defaultCursorHiDPI = NULL;- if (_glfw.wl.cursorThemeHiDPI)- {- defaultCursorHiDPI =- wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI, "left_ptr");- }-- _GLFWcursorWayland cursorWayland =- {- defaultCursor,- defaultCursorHiDPI,- NULL,- 0, 0,- 0, 0,- 0- };-- setCursorImage(window, &cursorWayland);- }- }- else if (window->cursorMode == GLFW_CURSOR_HIDDEN ||- window->cursorMode == GLFW_CURSOR_DISABLED)- {- wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, NULL, 0, 0);- }-}--static void dataSourceHandleTarget(void* userData,- struct wl_data_source* source,- const char* mimeType)-{- if (_glfw.wl.selectionSource != source)- {- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Unknown clipboard data source");- return;- }-}--static void dataSourceHandleSend(void* userData,- struct wl_data_source* source,- const char* mimeType,- int fd)-{- // Ignore it if this is an outdated or invalid request- if (_glfw.wl.selectionSource != source ||- strcmp(mimeType, "text/plain;charset=utf-8") != 0)- {- close(fd);- return;- }-- char* string = _glfw.wl.clipboardString;- size_t length = strlen(string);-- while (length > 0)- {- const ssize_t result = write(fd, string, length);- if (result == -1)- {- if (errno == EINTR)- continue;-- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Error while writing the clipboard: %s",- strerror(errno));- break;- }-- length -= result;- string += result;- }-- close(fd);-}--static void dataSourceHandleCancelled(void* userData,- struct wl_data_source* source)-{- wl_data_source_destroy(source);-- if (_glfw.wl.selectionSource != source)- return;-- _glfw.wl.selectionSource = NULL;-}--static const struct wl_data_source_listener dataSourceListener =-{- dataSourceHandleTarget,- dataSourceHandleSend,- dataSourceHandleCancelled,-};--void _glfwSetClipboardStringWayland(const char* string)-{- if (_glfw.wl.selectionSource)- {- wl_data_source_destroy(_glfw.wl.selectionSource);- _glfw.wl.selectionSource = NULL;- }-- char* copy = _glfw_strdup(string);- if (!copy)- {- _glfwInputError(GLFW_OUT_OF_MEMORY, NULL);- return;- }-- _glfw_free(_glfw.wl.clipboardString);- _glfw.wl.clipboardString = copy;-- _glfw.wl.selectionSource =- wl_data_device_manager_create_data_source(_glfw.wl.dataDeviceManager);- if (!_glfw.wl.selectionSource)- {- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to create clipboard data source");- return;- }- wl_data_source_add_listener(_glfw.wl.selectionSource,- &dataSourceListener,- NULL);- wl_data_source_offer(_glfw.wl.selectionSource, "text/plain;charset=utf-8");- wl_data_device_set_selection(_glfw.wl.dataDevice,- _glfw.wl.selectionSource,- _glfw.wl.serial);-}--const char* _glfwGetClipboardStringWayland(void)-{- if (!_glfw.wl.selectionOffer)- {- _glfwInputError(GLFW_FORMAT_UNAVAILABLE,- "Wayland: No clipboard data available");- return NULL;- }-- if (_glfw.wl.selectionSource)- return _glfw.wl.clipboardString;-- _glfw_free(_glfw.wl.clipboardString);- _glfw.wl.clipboardString =- readDataOfferAsString(_glfw.wl.selectionOffer, "text/plain;charset=utf-8");- return _glfw.wl.clipboardString;-}--EGLenum _glfwGetEGLPlatformWayland(EGLint** attribs)-{- if (_glfw.egl.EXT_platform_base && _glfw.egl.EXT_platform_wayland)- return EGL_PLATFORM_WAYLAND_EXT;- else- return 0;-}--EGLNativeDisplayType _glfwGetEGLNativeDisplayWayland(void)-{- return _glfw.wl.display;-}--EGLNativeWindowType _glfwGetEGLNativeWindowWayland(_GLFWwindow* window)-{- return window->wl.egl.window;-}--void _glfwGetRequiredInstanceExtensionsWayland(char** extensions)-{- if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_wayland_surface)- return;-- extensions[0] = "VK_KHR_surface";- extensions[1] = "VK_KHR_wayland_surface";-}--GLFWbool _glfwGetPhysicalDevicePresentationSupportWayland(VkInstance instance,- VkPhysicalDevice device,- uint32_t queuefamily)-{- PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR- vkGetPhysicalDeviceWaylandPresentationSupportKHR =- (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)- vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");- if (!vkGetPhysicalDeviceWaylandPresentationSupportKHR)- {- _glfwInputError(GLFW_API_UNAVAILABLE,- "Wayland: Vulkan instance missing VK_KHR_wayland_surface extension");- return VK_NULL_HANDLE;- }-- return vkGetPhysicalDeviceWaylandPresentationSupportKHR(device,- queuefamily,- _glfw.wl.display);-}--VkResult _glfwCreateWindowSurfaceWayland(VkInstance instance,- _GLFWwindow* window,- const VkAllocationCallbacks* allocator,- VkSurfaceKHR* surface)-{- VkResult err;- VkWaylandSurfaceCreateInfoKHR sci;- PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;-- vkCreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR)- vkGetInstanceProcAddr(instance, "vkCreateWaylandSurfaceKHR");- if (!vkCreateWaylandSurfaceKHR)- {- _glfwInputError(GLFW_API_UNAVAILABLE,- "Wayland: Vulkan instance missing VK_KHR_wayland_surface extension");- return VK_ERROR_EXTENSION_NOT_PRESENT;- }-- memset(&sci, 0, sizeof(sci));- sci.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;- sci.display = _glfw.wl.display;- sci.surface = window->wl.surface;-- err = vkCreateWaylandSurfaceKHR(instance, &sci, allocator, surface);- if (err)- {- _glfwInputError(GLFW_PLATFORM_ERROR,- "Wayland: Failed to create Vulkan surface: %s",- _glfwGetVulkanResultString(err));- }-- return err;-}---//////////////////////////////////////////////////////////////////////////-////// GLFW native API //////-//////////////////////////////////////////////////////////////////////////--GLFWAPI struct wl_display* glfwGetWaylandDisplay(void)-{- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);-- if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND)- {- _glfwInputError(GLFW_PLATFORM_UNAVAILABLE,- "Wayland: Platform not initialized");- return NULL;- }-- return _glfw.wl.display;-}--GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle)-{- _GLFWwindow* window = (_GLFWwindow*) handle;- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);-- if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND)- {- _glfwInputError(GLFW_PLATFORM_UNAVAILABLE,- "Wayland: Platform not initialized");- return NULL;- }-- return window->wl.surface;-}+// GLFW 3.4 Wayland (modified for raylib) - www.glfw.org; www.raylib.com+//------------------------------------------------------------------------+// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>+// Copyright (c) 2024 M374LX <wilsalx@gmail.com>+//+// This software is provided 'as-is', without any express or implied+// warranty. In no event will the authors be held liable for any damages+// arising from the use of this software.+//+// Permission is granted to anyone to use this software for any purpose,+// including commercial applications, and to alter it and redistribute it+// freely, subject to the following restrictions:+//+// 1. The origin of this software must not be misrepresented; you must not+// claim that you wrote the original software. If you use this software+// in a product, an acknowledgment in the product documentation would+// be appreciated but is not required.+//+// 2. Altered source versions must be plainly marked as such, and must not+// be misrepresented as being the original software.+//+// 3. This notice may not be removed or altered from any source+// distribution.+//+//========================================================================++#define _GNU_SOURCE++#include "internal.h"++#if defined(_GLFW_WAYLAND)++#include <stdio.h>+#include <stdlib.h>+#include <errno.h>+#include <assert.h>+#include <unistd.h>+#include <string.h>+#include <fcntl.h>+#include <sys/mman.h>+#include <sys/timerfd.h>+#include <poll.h>+#include <linux/input-event-codes.h>++#include "wayland-client-protocol.h"+#include "xdg-shell-client-protocol.h"+#include "xdg-decoration-unstable-v1-client-protocol.h"+#include "viewporter-client-protocol.h"+#include "relative-pointer-unstable-v1-client-protocol.h"+#include "pointer-constraints-unstable-v1-client-protocol.h"+#include "xdg-activation-v1-client-protocol.h"+#include "idle-inhibit-unstable-v1-client-protocol.h"+#include "fractional-scale-v1-client-protocol.h"++#define GLFW_BORDER_SIZE 4+#define GLFW_CAPTION_HEIGHT 24++static int createTmpfileCloexec(char* tmpname)+{+ int fd;++ fd = mkostemp(tmpname, O_CLOEXEC);+ if (fd >= 0)+ unlink(tmpname);++ return fd;+}++/*+ * Create a new, unique, anonymous file of the given size, and+ * return the file descriptor for it. The file descriptor is set+ * CLOEXEC. The file is immediately suitable for mmap()'ing+ * the given size at offset zero.+ *+ * The file should not have a permanent backing store like a disk,+ * but may have if XDG_RUNTIME_DIR is not properly implemented in OS.+ *+ * The file name is deleted from the file system.+ *+ * The file is suitable for buffer sharing between processes by+ * transmitting the file descriptor over Unix sockets using the+ * SCM_RIGHTS methods.+ *+ * posix_fallocate() is used to guarantee that disk space is available+ * for the file at the given size. If disk space is insufficient, errno+ * is set to ENOSPC. If posix_fallocate() is not supported, program may+ * receive SIGBUS on accessing mmap()'ed file contents instead.+ */+static int createAnonymousFile(off_t size)+{+ static const char template[] = "/glfw-shared-XXXXXX";+ const char* path;+ char* name;+ int fd;+ int ret;++#ifdef HAVE_MEMFD_CREATE+ fd = memfd_create("glfw-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING);+ if (fd >= 0)+ {+ // We can add this seal before calling posix_fallocate(), as the file+ // is currently zero-sized anyway.+ //+ // There is also no need to check for the return value, we couldn’t do+ // anything with it anyway.+ fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);+ }+ else+#elif defined(SHM_ANON)+ fd = shm_open(SHM_ANON, O_RDWR | O_CLOEXEC, 0600);+ if (fd < 0)+#endif+ {+ path = getenv("XDG_RUNTIME_DIR");+ if (!path)+ {+ errno = ENOENT;+ return -1;+ }++ name = _glfw_calloc(strlen(path) + sizeof(template), 1);+ strcpy(name, path);+ strcat(name, template);++ fd = createTmpfileCloexec(name);+ _glfw_free(name);+ if (fd < 0)+ return -1;+ }++#if defined(SHM_ANON)+ // posix_fallocate does not work on SHM descriptors+ ret = ftruncate(fd, size);+#else+ ret = posix_fallocate(fd, 0, size);+#endif+ if (ret != 0)+ {+ close(fd);+ errno = ret;+ return -1;+ }+ return fd;+}++static struct wl_buffer* createShmBuffer(const GLFWimage* image)+{+ const int stride = image->width * 4;+ const int length = image->width * image->height * 4;++ const int fd = createAnonymousFile(length);+ if (fd < 0)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to create buffer file of size %d: %s",+ length, strerror(errno));+ return NULL;+ }++ void* data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);+ if (data == MAP_FAILED)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to map file: %s", strerror(errno));+ close(fd);+ return NULL;+ }++ struct wl_shm_pool* pool = wl_shm_create_pool(_glfw.wl.shm, fd, length);++ close(fd);++ unsigned char* source = (unsigned char*) image->pixels;+ unsigned char* target = data;+ for (int i = 0; i < image->width * image->height; i++, source += 4)+ {+ unsigned int alpha = source[3];++ *target++ = (unsigned char) ((source[2] * alpha) / 255);+ *target++ = (unsigned char) ((source[1] * alpha) / 255);+ *target++ = (unsigned char) ((source[0] * alpha) / 255);+ *target++ = (unsigned char) alpha;+ }++ struct wl_buffer* buffer =+ wl_shm_pool_create_buffer(pool, 0,+ image->width,+ image->height,+ stride, WL_SHM_FORMAT_ARGB8888);+ munmap(data, length);+ wl_shm_pool_destroy(pool);++ return buffer;+}++static void createFallbackEdge(_GLFWwindow* window,+ _GLFWfallbackEdgeWayland* edge,+ struct wl_surface* parent,+ struct wl_buffer* buffer,+ int x, int y,+ int width, int height)+{+ edge->surface = wl_compositor_create_surface(_glfw.wl.compositor);+ wl_surface_set_user_data(edge->surface, window);+ wl_proxy_set_tag((struct wl_proxy*) edge->surface, &_glfw.wl.tag);+ edge->subsurface = wl_subcompositor_get_subsurface(_glfw.wl.subcompositor,+ edge->surface, parent);+ wl_subsurface_set_position(edge->subsurface, x, y);+ edge->viewport = wp_viewporter_get_viewport(_glfw.wl.viewporter,+ edge->surface);+ wp_viewport_set_destination(edge->viewport, width, height);+ wl_surface_attach(edge->surface, buffer, 0, 0);++ struct wl_region* region = wl_compositor_create_region(_glfw.wl.compositor);+ wl_region_add(region, 0, 0, width, height);+ wl_surface_set_opaque_region(edge->surface, region);+ wl_surface_commit(edge->surface);+ wl_region_destroy(region);+}++static void createFallbackDecorations(_GLFWwindow* window)+{+ unsigned char data[] = { 224, 224, 224, 255 };+ const GLFWimage image = { 1, 1, data };++ if (!_glfw.wl.viewporter)+ return;++ if (!window->wl.fallback.buffer)+ window->wl.fallback.buffer = createShmBuffer(&image);+ if (!window->wl.fallback.buffer)+ return;++ createFallbackEdge(window, &window->wl.fallback.top, window->wl.surface,+ window->wl.fallback.buffer,+ 0, -GLFW_CAPTION_HEIGHT,+ window->wl.width, GLFW_CAPTION_HEIGHT);+ createFallbackEdge(window, &window->wl.fallback.left, window->wl.surface,+ window->wl.fallback.buffer,+ -GLFW_BORDER_SIZE, -GLFW_CAPTION_HEIGHT,+ GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT);+ createFallbackEdge(window, &window->wl.fallback.right, window->wl.surface,+ window->wl.fallback.buffer,+ window->wl.width, -GLFW_CAPTION_HEIGHT,+ GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT);+ createFallbackEdge(window, &window->wl.fallback.bottom, window->wl.surface,+ window->wl.fallback.buffer,+ -GLFW_BORDER_SIZE, window->wl.height,+ window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE);++ window->wl.fallback.decorations = GLFW_TRUE;+}++static void destroyFallbackEdge(_GLFWfallbackEdgeWayland* edge)+{+ if (edge->subsurface)+ wl_subsurface_destroy(edge->subsurface);+ if (edge->surface)+ wl_surface_destroy(edge->surface);+ if (edge->viewport)+ wp_viewport_destroy(edge->viewport);++ edge->surface = NULL;+ edge->subsurface = NULL;+ edge->viewport = NULL;+}++static void destroyFallbackDecorations(_GLFWwindow* window)+{+ window->wl.fallback.decorations = GLFW_FALSE;++ destroyFallbackEdge(&window->wl.fallback.top);+ destroyFallbackEdge(&window->wl.fallback.left);+ destroyFallbackEdge(&window->wl.fallback.right);+ destroyFallbackEdge(&window->wl.fallback.bottom);+}++static void xdgDecorationHandleConfigure(void* userData,+ struct zxdg_toplevel_decoration_v1* decoration,+ uint32_t mode)+{+ _GLFWwindow* window = userData;++ window->wl.xdg.decorationMode = mode;++ if (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE)+ {+ if (window->decorated && !window->monitor)+ createFallbackDecorations(window);+ }+ else+ destroyFallbackDecorations(window);+}++static const struct zxdg_toplevel_decoration_v1_listener xdgDecorationListener =+{+ xdgDecorationHandleConfigure,+};++// Makes the surface considered as XRGB instead of ARGB.+static void setContentAreaOpaque(_GLFWwindow* window)+{+ struct wl_region* region;++ region = wl_compositor_create_region(_glfw.wl.compositor);+ if (!region)+ return;++ wl_region_add(region, 0, 0, window->wl.width, window->wl.height);+ wl_surface_set_opaque_region(window->wl.surface, region);+ wl_region_destroy(region);+}++static void resizeFramebuffer(_GLFWwindow* window)+{+ if (window->wl.fractionalScale)+ {+ window->wl.fbWidth = (window->wl.width * window->wl.scalingNumerator) / 120;+ window->wl.fbHeight = (window->wl.height * window->wl.scalingNumerator) / 120;+ }+ else+ {+ window->wl.fbWidth = window->wl.width * window->wl.bufferScale;+ window->wl.fbHeight = window->wl.height * window->wl.bufferScale;+ }++ if (window->wl.egl.window)+ {+ wl_egl_window_resize(window->wl.egl.window,+ window->wl.fbWidth,+ window->wl.fbHeight,+ 0, 0);+ }++ if (!window->wl.transparent)+ setContentAreaOpaque(window);++ _glfwInputFramebufferSize(window, window->wl.fbWidth, window->wl.fbHeight);+}++static GLFWbool resizeWindow(_GLFWwindow* window, int width, int height)+{+ width = _glfw_max(width, 1);+ height = _glfw_max(height, 1);++ if (width == window->wl.width && height == window->wl.height)+ return GLFW_FALSE;++ window->wl.width = width;+ window->wl.height = height;++ resizeFramebuffer(window);++ if (window->wl.scalingViewport)+ {+ wp_viewport_set_destination(window->wl.scalingViewport,+ window->wl.width,+ window->wl.height);+ }++ if (window->wl.fallback.decorations)+ {+ wp_viewport_set_destination(window->wl.fallback.top.viewport,+ window->wl.width,+ GLFW_CAPTION_HEIGHT);+ wl_surface_commit(window->wl.fallback.top.surface);++ wp_viewport_set_destination(window->wl.fallback.left.viewport,+ GLFW_BORDER_SIZE,+ window->wl.height + GLFW_CAPTION_HEIGHT);+ wl_surface_commit(window->wl.fallback.left.surface);++ wl_subsurface_set_position(window->wl.fallback.right.subsurface,+ window->wl.width, -GLFW_CAPTION_HEIGHT);+ wp_viewport_set_destination(window->wl.fallback.right.viewport,+ GLFW_BORDER_SIZE,+ window->wl.height + GLFW_CAPTION_HEIGHT);+ wl_surface_commit(window->wl.fallback.right.surface);++ wl_subsurface_set_position(window->wl.fallback.bottom.subsurface,+ -GLFW_BORDER_SIZE, window->wl.height);+ wp_viewport_set_destination(window->wl.fallback.bottom.viewport,+ window->wl.width + GLFW_BORDER_SIZE * 2,+ GLFW_BORDER_SIZE);+ wl_surface_commit(window->wl.fallback.bottom.surface);+ }++ return GLFW_TRUE;+}++void _glfwUpdateBufferScaleFromOutputsWayland(_GLFWwindow* window)+{+ if (wl_compositor_get_version(_glfw.wl.compositor) <+ WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)+ {+ return;+ }++ if (!window->wl.scaleFramebuffer)+ return;++ // When using fractional scaling, the buffer scale should remain at 1+ if (window->wl.fractionalScale)+ return;++ // Get the scale factor from the highest scale monitor.+ int32_t maxScale = 1;++ for (size_t i = 0; i < window->wl.outputScaleCount; i++)+ maxScale = _glfw_max(window->wl.outputScales[i].factor, maxScale);++ // Only change the framebuffer size if the scale changed.+ if (window->wl.bufferScale != maxScale)+ {+ window->wl.bufferScale = maxScale;+ wl_surface_set_buffer_scale(window->wl.surface, maxScale);+ _glfwInputWindowContentScale(window, maxScale, maxScale);+ resizeFramebuffer(window);++ if (window->wl.visible)+ _glfwInputWindowDamage(window);+ }+}++static void surfaceHandleEnter(void* userData,+ struct wl_surface* surface,+ struct wl_output* output)+{+ if (wl_proxy_get_tag((struct wl_proxy*) output) != &_glfw.wl.tag)+ return;++ _GLFWwindow* window = userData;+ _GLFWmonitor* monitor = wl_output_get_user_data(output);+ if (!window || !monitor)+ return;++ if (window->wl.outputScaleCount + 1 > window->wl.outputScaleSize)+ {+ window->wl.outputScaleSize++;+ window->wl.outputScales =+ _glfw_realloc(window->wl.outputScales,+ window->wl.outputScaleSize * sizeof(_GLFWscaleWayland));+ }++ window->wl.outputScaleCount++;+ window->wl.outputScales[window->wl.outputScaleCount - 1] =+ (_GLFWscaleWayland) { output, monitor->wl.scale };++ _glfwUpdateBufferScaleFromOutputsWayland(window);+}++static void surfaceHandleLeave(void* userData,+ struct wl_surface* surface,+ struct wl_output* output)+{+ if (wl_proxy_get_tag((struct wl_proxy*) output) != &_glfw.wl.tag)+ return;++ _GLFWwindow* window = userData;++ for (size_t i = 0; i < window->wl.outputScaleCount; i++)+ {+ if (window->wl.outputScales[i].output == output)+ {+ window->wl.outputScales[i] =+ window->wl.outputScales[window->wl.outputScaleCount - 1];+ window->wl.outputScaleCount--;+ break;+ }+ }++ _glfwUpdateBufferScaleFromOutputsWayland(window);+}++static const struct wl_surface_listener surfaceListener =+{+ surfaceHandleEnter,+ surfaceHandleLeave+};++static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable)+{+ if (enable && !window->wl.idleInhibitor && _glfw.wl.idleInhibitManager)+ {+ window->wl.idleInhibitor =+ zwp_idle_inhibit_manager_v1_create_inhibitor(+ _glfw.wl.idleInhibitManager, window->wl.surface);+ if (!window->wl.idleInhibitor)+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to create idle inhibitor");+ }+ else if (!enable && window->wl.idleInhibitor)+ {+ zwp_idle_inhibitor_v1_destroy(window->wl.idleInhibitor);+ window->wl.idleInhibitor = NULL;+ }+}++// Make the specified window and its video mode active on its monitor+//+static void acquireMonitorWayland(_GLFWwindow* window)+{+ if (window->wl.libdecor.frame)+ {+ libdecor_frame_set_fullscreen(window->wl.libdecor.frame,+ window->monitor->wl.output);+ }+ else if (window->wl.xdg.toplevel)+ {+ xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel,+ window->monitor->wl.output);+ }++ setIdleInhibitor(window, GLFW_TRUE);++ if (window->wl.fallback.decorations)+ destroyFallbackDecorations(window);+}++// Remove the window and restore the original video mode+//+static void releaseMonitorWayland(_GLFWwindow* window)+{+ if (window->wl.libdecor.frame)+ libdecor_frame_unset_fullscreen(window->wl.libdecor.frame);+ else if (window->wl.xdg.toplevel)+ xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);++ setIdleInhibitor(window, GLFW_FALSE);++ if (!window->wl.libdecor.frame &&+ window->wl.xdg.decorationMode != ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE)+ {+ if (window->decorated)+ createFallbackDecorations(window);+ }+}++void fractionalScaleHandlePreferredScale(void* userData,+ struct wp_fractional_scale_v1* fractionalScale,+ uint32_t numerator)+{+ _GLFWwindow* window = userData;++ window->wl.scalingNumerator = numerator;+ _glfwInputWindowContentScale(window, numerator / 120.f, numerator / 120.f);+ resizeFramebuffer(window);++ if (window->wl.visible)+ _glfwInputWindowDamage(window);+}++const struct wp_fractional_scale_v1_listener fractionalScaleListener =+{+ fractionalScaleHandlePreferredScale,+};++static void xdgToplevelHandleConfigure(void* userData,+ struct xdg_toplevel* toplevel,+ int32_t width,+ int32_t height,+ struct wl_array* states)+{+ _GLFWwindow* window = userData;+ uint32_t* state;++ window->wl.pending.activated = GLFW_FALSE;+ window->wl.pending.maximized = GLFW_FALSE;+ window->wl.pending.fullscreen = GLFW_FALSE;++ wl_array_for_each(state, states)+ {+ switch (*state)+ {+ case XDG_TOPLEVEL_STATE_MAXIMIZED:+ window->wl.pending.maximized = GLFW_TRUE;+ break;+ case XDG_TOPLEVEL_STATE_FULLSCREEN:+ window->wl.pending.fullscreen = GLFW_TRUE;+ break;+ case XDG_TOPLEVEL_STATE_RESIZING:+ break;+ case XDG_TOPLEVEL_STATE_ACTIVATED:+ window->wl.pending.activated = GLFW_TRUE;+ break;+ }+ }++ if (width && height)+ {+ if (window->wl.fallback.decorations)+ {+ window->wl.pending.width = _glfw_max(0, width - GLFW_BORDER_SIZE * 2);+ window->wl.pending.height =+ _glfw_max(0, height - GLFW_BORDER_SIZE - GLFW_CAPTION_HEIGHT);+ }+ else+ {+ window->wl.pending.width = width;+ window->wl.pending.height = height;+ }+ }+ else+ {+ window->wl.pending.width = window->wl.width;+ window->wl.pending.height = window->wl.height;+ }+}++static void xdgToplevelHandleClose(void* userData,+ struct xdg_toplevel* toplevel)+{+ _GLFWwindow* window = userData;+ _glfwInputWindowCloseRequest(window);+}++static const struct xdg_toplevel_listener xdgToplevelListener =+{+ xdgToplevelHandleConfigure,+ xdgToplevelHandleClose+};++static void xdgSurfaceHandleConfigure(void* userData,+ struct xdg_surface* surface,+ uint32_t serial)+{+ _GLFWwindow* window = userData;++ xdg_surface_ack_configure(surface, serial);++ if (window->wl.activated != window->wl.pending.activated)+ {+ window->wl.activated = window->wl.pending.activated;+ if (!window->wl.activated)+ {+ if (window->monitor && window->autoIconify)+ xdg_toplevel_set_minimized(window->wl.xdg.toplevel);+ }+ }++ if (window->wl.maximized != window->wl.pending.maximized)+ {+ window->wl.maximized = window->wl.pending.maximized;+ _glfwInputWindowMaximize(window, window->wl.maximized);+ }++ window->wl.fullscreen = window->wl.pending.fullscreen;++ int width = window->wl.pending.width;+ int height = window->wl.pending.height;++ if (!window->wl.maximized && !window->wl.fullscreen)+ {+ if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE)+ {+ const float aspectRatio = (float) width / (float) height;+ const float targetRatio = (float) window->numer / (float) window->denom;+ if (aspectRatio < targetRatio)+ height = width / targetRatio;+ else if (aspectRatio > targetRatio)+ width = height * targetRatio;+ }+ }++ if (resizeWindow(window, width, height))+ {+ _glfwInputWindowSize(window, window->wl.width, window->wl.height);++ if (window->wl.visible)+ _glfwInputWindowDamage(window);+ }++ if (!window->wl.visible)+ {+ // Allow the window to be mapped only if it either has no XDG+ // decorations or they have already received a configure event+ if (!window->wl.xdg.decoration || window->wl.xdg.decorationMode)+ {+ window->wl.visible = GLFW_TRUE;+ _glfwInputWindowDamage(window);+ }+ }+}++static const struct xdg_surface_listener xdgSurfaceListener =+{+ xdgSurfaceHandleConfigure+};++void libdecorFrameHandleConfigure(struct libdecor_frame* frame,+ struct libdecor_configuration* config,+ void* userData)+{+ _GLFWwindow* window = userData;+ int width, height;++ enum libdecor_window_state windowState;+ GLFWbool fullscreen, activated, maximized;++ if (libdecor_configuration_get_window_state(config, &windowState))+ {+ fullscreen = (windowState & LIBDECOR_WINDOW_STATE_FULLSCREEN) != 0;+ activated = (windowState & LIBDECOR_WINDOW_STATE_ACTIVE) != 0;+ maximized = (windowState & LIBDECOR_WINDOW_STATE_MAXIMIZED) != 0;+ }+ else+ {+ fullscreen = window->wl.fullscreen;+ activated = window->wl.activated;+ maximized = window->wl.maximized;+ }++ if (!libdecor_configuration_get_content_size(config, frame, &width, &height))+ {+ width = window->wl.width;+ height = window->wl.height;+ }++ if (!maximized && !fullscreen)+ {+ if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE)+ {+ const float aspectRatio = (float) width / (float) height;+ const float targetRatio = (float) window->numer / (float) window->denom;+ if (aspectRatio < targetRatio)+ height = width / targetRatio;+ else if (aspectRatio > targetRatio)+ width = height * targetRatio;+ }+ }++ struct libdecor_state* frameState = libdecor_state_new(width, height);+ libdecor_frame_commit(frame, frameState, config);+ libdecor_state_free(frameState);++ if (window->wl.activated != activated)+ {+ window->wl.activated = activated;+ if (!window->wl.activated)+ {+ if (window->monitor && window->autoIconify)+ libdecor_frame_set_minimized(window->wl.libdecor.frame);+ }+ }++ if (window->wl.maximized != maximized)+ {+ window->wl.maximized = maximized;+ _glfwInputWindowMaximize(window, window->wl.maximized);+ }++ window->wl.fullscreen = fullscreen;++ GLFWbool damaged = GLFW_FALSE;++ if (!window->wl.visible)+ {+ window->wl.visible = GLFW_TRUE;+ damaged = GLFW_TRUE;+ }++ if (resizeWindow(window, width, height))+ {+ _glfwInputWindowSize(window, window->wl.width, window->wl.height);+ damaged = GLFW_TRUE;+ }++ if (damaged)+ _glfwInputWindowDamage(window);+ else+ wl_surface_commit(window->wl.surface);+}++void libdecorFrameHandleClose(struct libdecor_frame* frame, void* userData)+{+ _GLFWwindow* window = userData;+ _glfwInputWindowCloseRequest(window);+}++void libdecorFrameHandleCommit(struct libdecor_frame* frame, void* userData)+{+ _GLFWwindow* window = userData;+ wl_surface_commit(window->wl.surface);+}++void libdecorFrameHandleDismissPopup(struct libdecor_frame* frame,+ const char* seatName,+ void* userData)+{+}++static const struct libdecor_frame_interface libdecorFrameInterface =+{+ libdecorFrameHandleConfigure,+ libdecorFrameHandleClose,+ libdecorFrameHandleCommit,+ libdecorFrameHandleDismissPopup+};++static GLFWbool createLibdecorFrame(_GLFWwindow* window)+{+ // Allow libdecor to finish initialization of itself and its plugin+ while (!_glfw.wl.libdecor.ready)+ _glfwWaitEventsWayland();++ window->wl.libdecor.frame = libdecor_decorate(_glfw.wl.libdecor.context,+ window->wl.surface,+ &libdecorFrameInterface,+ window);+ if (!window->wl.libdecor.frame)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to create libdecor frame");+ return GLFW_FALSE;+ }++ struct libdecor_state* frameState =+ libdecor_state_new(window->wl.width, window->wl.height);+ libdecor_frame_commit(window->wl.libdecor.frame, frameState, NULL);+ libdecor_state_free(frameState);++ if (strlen(window->wl.appId))+ libdecor_frame_set_app_id(window->wl.libdecor.frame, window->wl.appId);++ libdecor_frame_set_title(window->wl.libdecor.frame, window->title);++ if (window->minwidth != GLFW_DONT_CARE &&+ window->minheight != GLFW_DONT_CARE)+ {+ libdecor_frame_set_min_content_size(window->wl.libdecor.frame,+ window->minwidth,+ window->minheight);+ }++ if (window->maxwidth != GLFW_DONT_CARE &&+ window->maxheight != GLFW_DONT_CARE)+ {+ libdecor_frame_set_max_content_size(window->wl.libdecor.frame,+ window->maxwidth,+ window->maxheight);+ }++ if (!window->resizable)+ {+ libdecor_frame_unset_capabilities(window->wl.libdecor.frame,+ LIBDECOR_ACTION_RESIZE);+ }++ if (window->monitor)+ {+ libdecor_frame_set_fullscreen(window->wl.libdecor.frame,+ window->monitor->wl.output);+ setIdleInhibitor(window, GLFW_TRUE);+ }+ else+ {+ if (window->wl.maximized)+ libdecor_frame_set_maximized(window->wl.libdecor.frame);++ if (!window->decorated)+ libdecor_frame_set_visibility(window->wl.libdecor.frame, false);++ setIdleInhibitor(window, GLFW_FALSE);+ }++ libdecor_frame_map(window->wl.libdecor.frame);+ wl_display_roundtrip(_glfw.wl.display);+ return GLFW_TRUE;+}++static void updateXdgSizeLimits(_GLFWwindow* window)+{+ int minwidth, minheight, maxwidth, maxheight;++ if (window->resizable)+ {+ if (window->minwidth == GLFW_DONT_CARE || window->minheight == GLFW_DONT_CARE)+ minwidth = minheight = 0;+ else+ {+ minwidth = window->minwidth;+ minheight = window->minheight;++ if (window->wl.fallback.decorations)+ {+ minwidth += GLFW_BORDER_SIZE * 2;+ minheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE;+ }+ }++ if (window->maxwidth == GLFW_DONT_CARE || window->maxheight == GLFW_DONT_CARE)+ maxwidth = maxheight = 0;+ else+ {+ maxwidth = window->maxwidth;+ maxheight = window->maxheight;++ if (window->wl.fallback.decorations)+ {+ maxwidth += GLFW_BORDER_SIZE * 2;+ maxheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE;+ }+ }+ }+ else+ {+ minwidth = maxwidth = window->wl.width;+ minheight = maxheight = window->wl.height;+ }++ xdg_toplevel_set_min_size(window->wl.xdg.toplevel, minwidth, minheight);+ xdg_toplevel_set_max_size(window->wl.xdg.toplevel, maxwidth, maxheight);+}++static GLFWbool createXdgShellObjects(_GLFWwindow* window)+{+ window->wl.xdg.surface = xdg_wm_base_get_xdg_surface(_glfw.wl.wmBase,+ window->wl.surface);+ if (!window->wl.xdg.surface)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to create xdg-surface for window");+ return GLFW_FALSE;+ }++ xdg_surface_add_listener(window->wl.xdg.surface, &xdgSurfaceListener, window);++ window->wl.xdg.toplevel = xdg_surface_get_toplevel(window->wl.xdg.surface);+ if (!window->wl.xdg.toplevel)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to create xdg-toplevel for window");+ return GLFW_FALSE;+ }++ xdg_toplevel_add_listener(window->wl.xdg.toplevel, &xdgToplevelListener, window);++ if (window->wl.appId)+ xdg_toplevel_set_app_id(window->wl.xdg.toplevel, window->wl.appId);++ xdg_toplevel_set_title(window->wl.xdg.toplevel, window->title);++ if (window->monitor)+ {+ xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel, window->monitor->wl.output);+ setIdleInhibitor(window, GLFW_TRUE);+ }+ else+ {+ if (window->wl.maximized)+ xdg_toplevel_set_maximized(window->wl.xdg.toplevel);++ setIdleInhibitor(window, GLFW_FALSE);+ }++ if (_glfw.wl.decorationManager)+ {+ window->wl.xdg.decoration =+ zxdg_decoration_manager_v1_get_toplevel_decoration(+ _glfw.wl.decorationManager, window->wl.xdg.toplevel);+ zxdg_toplevel_decoration_v1_add_listener(window->wl.xdg.decoration,+ &xdgDecorationListener,+ window);++ uint32_t mode;++ if (window->decorated)+ mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE;+ else+ mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;++ zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode);+ }+ else+ {+ if (window->decorated && !window->monitor)+ createFallbackDecorations(window);+ }++ updateXdgSizeLimits(window);++ wl_surface_commit(window->wl.surface);+ wl_display_roundtrip(_glfw.wl.display);+ return GLFW_TRUE;+}++static GLFWbool createShellObjects(_GLFWwindow* window)+{+ if (_glfw.wl.libdecor.context)+ {+ if (createLibdecorFrame(window))+ return GLFW_TRUE;+ }++ return createXdgShellObjects(window);+}++static void destroyShellObjects(_GLFWwindow* window)+{+ destroyFallbackDecorations(window);++ if (window->wl.libdecor.frame)+ libdecor_frame_unref(window->wl.libdecor.frame);++ if (window->wl.xdg.decoration)+ zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration);++ if (window->wl.xdg.toplevel)+ xdg_toplevel_destroy(window->wl.xdg.toplevel);++ if (window->wl.xdg.surface)+ xdg_surface_destroy(window->wl.xdg.surface);++ window->wl.libdecor.frame = NULL;+ window->wl.xdg.decoration = NULL;+ window->wl.xdg.decorationMode = 0;+ window->wl.xdg.toplevel = NULL;+ window->wl.xdg.surface = NULL;+}++static GLFWbool createNativeSurface(_GLFWwindow* window,+ const _GLFWwndconfig* wndconfig,+ const _GLFWfbconfig* fbconfig)+{+ window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor);+ if (!window->wl.surface)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Failed to create window surface");+ return GLFW_FALSE;+ }++ wl_proxy_set_tag((struct wl_proxy*) window->wl.surface, &_glfw.wl.tag);+ wl_surface_add_listener(window->wl.surface,+ &surfaceListener,+ window);++ window->wl.width = wndconfig->width;+ window->wl.height = wndconfig->height;+ window->wl.fbWidth = wndconfig->width;+ window->wl.fbHeight = wndconfig->height;+ window->wl.appId = _glfw_strdup(wndconfig->wl.appId);++ window->wl.bufferScale = 1;+ window->wl.scalingNumerator = 120;+ window->wl.scaleFramebuffer = wndconfig->scaleFramebuffer;++ window->wl.maximized = wndconfig->maximized;++ window->wl.transparent = fbconfig->transparent;+ if (!window->wl.transparent)+ setContentAreaOpaque(window);++ if (_glfw.wl.fractionalScaleManager)+ {+ if (window->wl.scaleFramebuffer)+ {+ window->wl.scalingViewport =+ wp_viewporter_get_viewport(_glfw.wl.viewporter, window->wl.surface);++ wp_viewport_set_destination(window->wl.scalingViewport,+ window->wl.width,+ window->wl.height);++ window->wl.fractionalScale =+ wp_fractional_scale_manager_v1_get_fractional_scale(+ _glfw.wl.fractionalScaleManager,+ window->wl.surface);++ wp_fractional_scale_v1_add_listener(window->wl.fractionalScale,+ &fractionalScaleListener,+ window);+ }+ }++ return GLFW_TRUE;+}++static void setCursorImage(_GLFWwindow* window,+ _GLFWcursorWayland* cursorWayland)+{+ struct itimerspec timer = {0};+ struct wl_cursor* wlCursor = cursorWayland->cursor;+ struct wl_cursor_image* image;+ struct wl_buffer* buffer;+ struct wl_surface* surface = _glfw.wl.cursorSurface;+ int scale = 1;++ if (!wlCursor)+ buffer = cursorWayland->buffer;+ else+ {+ if (window->wl.bufferScale > 1 && cursorWayland->cursorHiDPI)+ {+ wlCursor = cursorWayland->cursorHiDPI;+ scale = 2;+ }++ image = wlCursor->images[cursorWayland->currentImage];+ buffer = wl_cursor_image_get_buffer(image);+ if (!buffer)+ return;++ timer.it_value.tv_sec = image->delay / 1000;+ timer.it_value.tv_nsec = (image->delay % 1000) * 1000000;+ timerfd_settime(_glfw.wl.cursorTimerfd, 0, &timer, NULL);++ cursorWayland->width = image->width;+ cursorWayland->height = image->height;+ cursorWayland->xhot = image->hotspot_x;+ cursorWayland->yhot = image->hotspot_y;+ }++ wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial,+ surface,+ cursorWayland->xhot / scale,+ cursorWayland->yhot / scale);+ wl_surface_set_buffer_scale(surface, scale);+ wl_surface_attach(surface, buffer, 0, 0);+ wl_surface_damage(surface, 0, 0,+ cursorWayland->width, cursorWayland->height);+ wl_surface_commit(surface);+}++static void incrementCursorImage(_GLFWwindow* window)+{+ _GLFWcursor* cursor;++ if (!window || !window->wl.hovered)+ return;++ cursor = window->wl.currentCursor;+ if (cursor && cursor->wl.cursor)+ {+ cursor->wl.currentImage += 1;+ cursor->wl.currentImage %= cursor->wl.cursor->image_count;+ setCursorImage(window, &cursor->wl);+ }+}++static GLFWbool flushDisplay(void)+{+ while (wl_display_flush(_glfw.wl.display) == -1)+ {+ if (errno != EAGAIN)+ return GLFW_FALSE;++ struct pollfd fd = { wl_display_get_fd(_glfw.wl.display), POLLOUT };++ while (poll(&fd, 1, -1) == -1)+ {+ if (errno != EINTR && errno != EAGAIN)+ return GLFW_FALSE;+ }+ }++ return GLFW_TRUE;+}++static int translateKeyWayland(uint32_t scancode)+{+ if (scancode < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0]))+ return _glfw.wl.keycodes[scancode];++ return GLFW_KEY_UNKNOWN;+}++static xkb_keysym_t composeSymbol(xkb_keysym_t sym)+{+ if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState)+ return sym;+ if (xkb_compose_state_feed(_glfw.wl.xkb.composeState, sym)+ != XKB_COMPOSE_FEED_ACCEPTED)+ return sym;+ switch (xkb_compose_state_get_status(_glfw.wl.xkb.composeState))+ {+ case XKB_COMPOSE_COMPOSED:+ return xkb_compose_state_get_one_sym(_glfw.wl.xkb.composeState);+ case XKB_COMPOSE_COMPOSING:+ case XKB_COMPOSE_CANCELLED:+ return XKB_KEY_NoSymbol;+ case XKB_COMPOSE_NOTHING:+ default:+ return sym;+ }+}++static void inputText(_GLFWwindow* window, uint32_t scancode)+{+ const xkb_keysym_t* keysyms;+ const xkb_keycode_t keycode = scancode + 8;++ if (xkb_state_key_get_syms(_glfw.wl.xkb.state, keycode, &keysyms) == 1)+ {+ const xkb_keysym_t keysym = composeSymbol(keysyms[0]);+ const uint32_t codepoint = _glfwKeySym2Unicode(keysym);+ if (codepoint != GLFW_INVALID_CODEPOINT)+ {+ const int mods = _glfw.wl.xkb.modifiers;+ const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));+ _glfwInputChar(window, codepoint, mods, plain);+ }+ }+}++static void handleEvents(double* timeout)+{+#if defined(GLFW_BUILD_LINUX_JOYSTICK)+ if (_glfw.joysticksInitialized)+ _glfwDetectJoystickConnectionLinux();+#endif++ GLFWbool event = GLFW_FALSE;+ enum { DISPLAY_FD, KEYREPEAT_FD, CURSOR_FD, LIBDECOR_FD };+ struct pollfd fds[] =+ {+ [DISPLAY_FD] = { wl_display_get_fd(_glfw.wl.display), POLLIN },+ [KEYREPEAT_FD] = { _glfw.wl.keyRepeatTimerfd, POLLIN },+ [CURSOR_FD] = { _glfw.wl.cursorTimerfd, POLLIN },+ [LIBDECOR_FD] = { -1, POLLIN }+ };++ if (_glfw.wl.libdecor.context)+ fds[LIBDECOR_FD].fd = libdecor_get_fd(_glfw.wl.libdecor.context);++ while (!event)+ {+ while (wl_display_prepare_read(_glfw.wl.display) != 0)+ {+ if (wl_display_dispatch_pending(_glfw.wl.display) > 0)+ return;+ }++ // If an error other than EAGAIN happens, we have likely been disconnected+ // from the Wayland session; try to handle that the best we can.+ if (!flushDisplay())+ {+ wl_display_cancel_read(_glfw.wl.display);++ _GLFWwindow* window = _glfw.windowListHead;+ while (window)+ {+ _glfwInputWindowCloseRequest(window);+ window = window->next;+ }++ return;+ }++ if (!_glfwPollPOSIX(fds, sizeof(fds) / sizeof(fds[0]), timeout))+ {+ wl_display_cancel_read(_glfw.wl.display);+ return;+ }++ if (fds[DISPLAY_FD].revents & POLLIN)+ {+ wl_display_read_events(_glfw.wl.display);+ if (wl_display_dispatch_pending(_glfw.wl.display) > 0)+ event = GLFW_TRUE;+ }+ else+ wl_display_cancel_read(_glfw.wl.display);++ if (fds[KEYREPEAT_FD].revents & POLLIN)+ {+ uint64_t repeats;++ if (read(_glfw.wl.keyRepeatTimerfd, &repeats, sizeof(repeats)) == 8)+ {+ for (uint64_t i = 0; i < repeats; i++)+ {+ _glfwInputKey(_glfw.wl.keyboardFocus,+ translateKeyWayland(_glfw.wl.keyRepeatScancode),+ _glfw.wl.keyRepeatScancode,+ GLFW_PRESS,+ _glfw.wl.xkb.modifiers);+ inputText(_glfw.wl.keyboardFocus, _glfw.wl.keyRepeatScancode);+ }++ event = GLFW_TRUE;+ }+ }++ if (fds[CURSOR_FD].revents & POLLIN)+ {+ uint64_t repeats;++ if (read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats)) == 8)+ incrementCursorImage(_glfw.wl.pointerFocus);+ }++ if (fds[LIBDECOR_FD].revents & POLLIN)+ {+ if (libdecor_dispatch(_glfw.wl.libdecor.context, 0) > 0)+ event = GLFW_TRUE;+ }+ }+}++// Reads the specified data offer as the specified MIME type+//+static char* readDataOfferAsString(struct wl_data_offer* offer, const char* mimeType)+{+ int fds[2];++ if (pipe2(fds, O_CLOEXEC) == -1)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to create pipe for data offer: %s",+ strerror(errno));+ return NULL;+ }++ wl_data_offer_receive(offer, mimeType, fds[1]);+ flushDisplay();+ close(fds[1]);++ char* string = NULL;+ size_t size = 0;+ size_t length = 0;++ for (;;)+ {+ const size_t readSize = 4096;+ const size_t requiredSize = length + readSize + 1;+ if (requiredSize > size)+ {+ char* longer = _glfw_realloc(string, requiredSize);+ if (!longer)+ {+ _glfwInputError(GLFW_OUT_OF_MEMORY, NULL);+ close(fds[0]);+ return NULL;+ }++ string = longer;+ size = requiredSize;+ }++ const ssize_t result = read(fds[0], string + length, readSize);+ if (result == 0)+ break;+ else if (result == -1)+ {+ if (errno == EINTR)+ continue;++ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to read from data offer pipe: %s",+ strerror(errno));+ close(fds[0]);+ return NULL;+ }++ length += result;+ }++ close(fds[0]);++ string[length] = '\0';+ return string;+}++static void pointerHandleEnter(void* userData,+ struct wl_pointer* pointer,+ uint32_t serial,+ struct wl_surface* surface,+ wl_fixed_t sx,+ wl_fixed_t sy)+{+ // Happens in the case we just destroyed the surface.+ if (!surface)+ return;++ if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag)+ return;++ _GLFWwindow* window = wl_surface_get_user_data(surface);++ _glfw.wl.serial = serial;+ _glfw.wl.pointerEnterSerial = serial;+ _glfw.wl.pointerFocus = window;++ if (surface == window->wl.surface)+ {+ window->wl.hovered = GLFW_TRUE;+ _glfwSetCursorWayland(window, window->wl.currentCursor);+ _glfwInputCursorEnter(window, GLFW_TRUE);+ }+ else+ {+ if (window->wl.fallback.decorations)+ window->wl.fallback.focus = surface;+ }+}++static void pointerHandleLeave(void* userData,+ struct wl_pointer* pointer,+ uint32_t serial,+ struct wl_surface* surface)+{+ if (!surface)+ return;++ if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag)+ return;++ _GLFWwindow* window = _glfw.wl.pointerFocus;+ if (!window)+ return;++ _glfw.wl.serial = serial;+ _glfw.wl.pointerFocus = NULL;+ _glfw.wl.cursorPreviousName = NULL;++ if (window->wl.hovered)+ {+ window->wl.hovered = GLFW_FALSE;+ _glfwInputCursorEnter(window, GLFW_FALSE);+ }+ else+ {+ if (window->wl.fallback.decorations)+ window->wl.fallback.focus = NULL;+ }+}++static void pointerHandleMotion(void* userData,+ struct wl_pointer* pointer,+ uint32_t time,+ wl_fixed_t sx,+ wl_fixed_t sy)+{+ _GLFWwindow* window = _glfw.wl.pointerFocus;+ if (!window)+ return;++ if (window->cursorMode == GLFW_CURSOR_DISABLED)+ return;++ const double xpos = wl_fixed_to_double(sx);+ const double ypos = wl_fixed_to_double(sy);+ window->wl.cursorPosX = xpos;+ window->wl.cursorPosY = ypos;++ if (window->wl.hovered)+ {+ _glfw.wl.cursorPreviousName = NULL;+ _glfwInputCursorPos(window, xpos, ypos);+ return;+ }++ if (window->wl.fallback.decorations)+ {+ const char* cursorName = "left_ptr";++ if (window->resizable)+ {+ if (window->wl.fallback.focus == window->wl.fallback.top.surface)+ {+ if (ypos < GLFW_BORDER_SIZE)+ cursorName = "n-resize";+ }+ else if (window->wl.fallback.focus == window->wl.fallback.left.surface)+ {+ if (ypos < GLFW_BORDER_SIZE)+ cursorName = "nw-resize";+ else+ cursorName = "w-resize";+ }+ else if (window->wl.fallback.focus == window->wl.fallback.right.surface)+ {+ if (ypos < GLFW_BORDER_SIZE)+ cursorName = "ne-resize";+ else+ cursorName = "e-resize";+ }+ else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface)+ {+ if (xpos < GLFW_BORDER_SIZE)+ cursorName = "sw-resize";+ else if (xpos > window->wl.width + GLFW_BORDER_SIZE)+ cursorName = "se-resize";+ else+ cursorName = "s-resize";+ }+ }++ if (_glfw.wl.cursorPreviousName != cursorName)+ {+ struct wl_surface* surface = _glfw.wl.cursorSurface;+ struct wl_cursor_theme* theme = _glfw.wl.cursorTheme;+ int scale = 1;++ if (window->wl.bufferScale > 1 && _glfw.wl.cursorThemeHiDPI)+ {+ // We only support up to scale=2 for now, since libwayland-cursor+ // requires us to load a different theme for each size.+ scale = 2;+ theme = _glfw.wl.cursorThemeHiDPI;+ }++ struct wl_cursor* cursor = wl_cursor_theme_get_cursor(theme, cursorName);+ if (!cursor)+ return;++ // TODO: handle animated cursors too.+ struct wl_cursor_image* image = cursor->images[0];+ if (!image)+ return;++ struct wl_buffer* buffer = wl_cursor_image_get_buffer(image);+ if (!buffer)+ return;++ wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial,+ surface,+ image->hotspot_x / scale,+ image->hotspot_y / scale);+ wl_surface_set_buffer_scale(surface, scale);+ wl_surface_attach(surface, buffer, 0, 0);+ wl_surface_damage(surface, 0, 0, image->width, image->height);+ wl_surface_commit(surface);++ _glfw.wl.cursorPreviousName = cursorName;+ }+ }+}++static void pointerHandleButton(void* userData,+ struct wl_pointer* pointer,+ uint32_t serial,+ uint32_t time,+ uint32_t button,+ uint32_t state)+{+ _GLFWwindow* window = _glfw.wl.pointerFocus;+ if (!window)+ return;++ if (window->wl.hovered)+ {+ _glfw.wl.serial = serial;++ _glfwInputMouseClick(window,+ button - BTN_LEFT,+ state == WL_POINTER_BUTTON_STATE_PRESSED,+ _glfw.wl.xkb.modifiers);+ return;+ }++ if (window->wl.fallback.decorations)+ {+ if (button == BTN_LEFT)+ {+ uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;++ if (window->wl.fallback.focus == window->wl.fallback.top.surface)+ {+ if (window->wl.cursorPosY < GLFW_BORDER_SIZE)+ edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;+ else+ xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);+ }+ else if (window->wl.fallback.focus == window->wl.fallback.left.surface)+ {+ if (window->wl.cursorPosY < GLFW_BORDER_SIZE)+ edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;+ else+ edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;+ }+ else if (window->wl.fallback.focus == window->wl.fallback.right.surface)+ {+ if (window->wl.cursorPosY < GLFW_BORDER_SIZE)+ edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;+ else+ edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;+ }+ else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface)+ {+ if (window->wl.cursorPosX < GLFW_BORDER_SIZE)+ edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;+ else if (window->wl.cursorPosX > window->wl.width + GLFW_BORDER_SIZE)+ edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;+ else+ edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;+ }++ if (edges != XDG_TOPLEVEL_RESIZE_EDGE_NONE)+ {+ xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat,+ serial, edges);+ }+ }+ else if (button == BTN_RIGHT)+ {+ if (window->wl.xdg.toplevel)+ {+ xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,+ _glfw.wl.seat, serial,+ window->wl.cursorPosX,+ window->wl.cursorPosY);+ }+ }+ }+}++static void pointerHandleAxis(void* userData,+ struct wl_pointer* pointer,+ uint32_t time,+ uint32_t axis,+ wl_fixed_t value)+{+ _GLFWwindow* window = _glfw.wl.pointerFocus;+ if (!window)+ return;++ // NOTE: 10 units of motion per mouse wheel step seems to be a common ratio+ if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)+ _glfwInputScroll(window, -wl_fixed_to_double(value) / 10.0, 0.0);+ else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)+ _glfwInputScroll(window, 0.0, -wl_fixed_to_double(value) / 10.0);+}++static const struct wl_pointer_listener pointerListener =+{+ pointerHandleEnter,+ pointerHandleLeave,+ pointerHandleMotion,+ pointerHandleButton,+ pointerHandleAxis,+};++static void keyboardHandleKeymap(void* userData,+ struct wl_keyboard* keyboard,+ uint32_t format,+ int fd,+ uint32_t size)+{+ struct xkb_keymap* keymap;+ struct xkb_state* state;+ struct xkb_compose_table* composeTable;+ struct xkb_compose_state* composeState;++ char* mapStr;+ const char* locale;++ if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)+ {+ close(fd);+ return;+ }++ mapStr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);+ if (mapStr == MAP_FAILED) {+ close(fd);+ return;+ }++ keymap = xkb_keymap_new_from_string(_glfw.wl.xkb.context,+ mapStr,+ XKB_KEYMAP_FORMAT_TEXT_V1,+ 0);+ munmap(mapStr, size);+ close(fd);++ if (!keymap)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to compile keymap");+ return;+ }++ state = xkb_state_new(keymap);+ if (!state)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to create XKB state");+ xkb_keymap_unref(keymap);+ return;+ }++ // Look up the preferred locale, falling back to "C" as default.+ locale = getenv("LC_ALL");+ if (!locale)+ locale = getenv("LC_CTYPE");+ if (!locale)+ locale = getenv("LANG");+ if (!locale)+ locale = "C";++ composeTable =+ xkb_compose_table_new_from_locale(_glfw.wl.xkb.context, locale,+ XKB_COMPOSE_COMPILE_NO_FLAGS);+ if (composeTable)+ {+ composeState =+ xkb_compose_state_new(composeTable, XKB_COMPOSE_STATE_NO_FLAGS);+ xkb_compose_table_unref(composeTable);+ if (composeState)+ _glfw.wl.xkb.composeState = composeState;+ else+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to create XKB compose state");+ }+ else+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to create XKB compose table");+ }++ xkb_keymap_unref(_glfw.wl.xkb.keymap);+ xkb_state_unref(_glfw.wl.xkb.state);+ _glfw.wl.xkb.keymap = keymap;+ _glfw.wl.xkb.state = state;++ _glfw.wl.xkb.controlIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Control");+ _glfw.wl.xkb.altIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod1");+ _glfw.wl.xkb.shiftIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Shift");+ _glfw.wl.xkb.superIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod4");+ _glfw.wl.xkb.capsLockIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Lock");+ _glfw.wl.xkb.numLockIndex = xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod2");+}++static void keyboardHandleEnter(void* userData,+ struct wl_keyboard* keyboard,+ uint32_t serial,+ struct wl_surface* surface,+ struct wl_array* keys)+{+ // Happens in the case we just destroyed the surface.+ if (!surface)+ return;++ if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag)+ return;++ _GLFWwindow* window = wl_surface_get_user_data(surface);+ if (surface != window->wl.surface)+ return;++ _glfw.wl.serial = serial;+ _glfw.wl.keyboardFocus = window;+ _glfwInputWindowFocus(window, GLFW_TRUE);+}++static void keyboardHandleLeave(void* userData,+ struct wl_keyboard* keyboard,+ uint32_t serial,+ struct wl_surface* surface)+{+ _GLFWwindow* window = _glfw.wl.keyboardFocus;++ if (!window)+ return;++ struct itimerspec timer = {0};+ timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);++ _glfw.wl.serial = serial;+ _glfw.wl.keyboardFocus = NULL;+ _glfwInputWindowFocus(window, GLFW_FALSE);+}++static void keyboardHandleKey(void* userData,+ struct wl_keyboard* keyboard,+ uint32_t serial,+ uint32_t time,+ uint32_t scancode,+ uint32_t state)+{+ _GLFWwindow* window = _glfw.wl.keyboardFocus;+ if (!window)+ return;++ const int key = translateKeyWayland(scancode);+ const int action =+ state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE;++ _glfw.wl.serial = serial;++ struct itimerspec timer = {0};++ if (action == GLFW_PRESS)+ {+ const xkb_keycode_t keycode = scancode + 8;++ if (xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode) &&+ _glfw.wl.keyRepeatRate > 0)+ {+ _glfw.wl.keyRepeatScancode = scancode;+ if (_glfw.wl.keyRepeatRate > 1)+ timer.it_interval.tv_nsec = 1000000000 / _glfw.wl.keyRepeatRate;+ else+ timer.it_interval.tv_sec = 1;++ timer.it_value.tv_sec = _glfw.wl.keyRepeatDelay / 1000;+ timer.it_value.tv_nsec = (_glfw.wl.keyRepeatDelay % 1000) * 1000000;+ }+ }++ timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);++ _glfwInputKey(window, key, scancode, action, _glfw.wl.xkb.modifiers);++ if (action == GLFW_PRESS)+ inputText(window, scancode);+}++static void keyboardHandleModifiers(void* userData,+ struct wl_keyboard* keyboard,+ uint32_t serial,+ uint32_t modsDepressed,+ uint32_t modsLatched,+ uint32_t modsLocked,+ uint32_t group)+{+ _glfw.wl.serial = serial;++ if (!_glfw.wl.xkb.keymap)+ return;++ xkb_state_update_mask(_glfw.wl.xkb.state,+ modsDepressed,+ modsLatched,+ modsLocked,+ 0,+ 0,+ group);++ _glfw.wl.xkb.modifiers = 0;++ struct+ {+ xkb_mod_index_t index;+ unsigned int bit;+ } modifiers[] =+ {+ { _glfw.wl.xkb.controlIndex, GLFW_MOD_CONTROL },+ { _glfw.wl.xkb.altIndex, GLFW_MOD_ALT },+ { _glfw.wl.xkb.shiftIndex, GLFW_MOD_SHIFT },+ { _glfw.wl.xkb.superIndex, GLFW_MOD_SUPER },+ { _glfw.wl.xkb.capsLockIndex, GLFW_MOD_CAPS_LOCK },+ { _glfw.wl.xkb.numLockIndex, GLFW_MOD_NUM_LOCK }+ };++ for (size_t i = 0; i < sizeof(modifiers) / sizeof(modifiers[0]); i++)+ {+ if (xkb_state_mod_index_is_active(_glfw.wl.xkb.state,+ modifiers[i].index,+ XKB_STATE_MODS_EFFECTIVE) == 1)+ {+ _glfw.wl.xkb.modifiers |= modifiers[i].bit;+ }+ }+}++static void keyboardHandleRepeatInfo(void* userData,+ struct wl_keyboard* keyboard,+ int32_t rate,+ int32_t delay)+{+ if (keyboard != _glfw.wl.keyboard)+ return;++ _glfw.wl.keyRepeatRate = rate;+ _glfw.wl.keyRepeatDelay = delay;+}++static const struct wl_keyboard_listener keyboardListener =+{+ keyboardHandleKeymap,+ keyboardHandleEnter,+ keyboardHandleLeave,+ keyboardHandleKey,+ keyboardHandleModifiers,+ keyboardHandleRepeatInfo,+};++static void seatHandleCapabilities(void* userData,+ struct wl_seat* seat,+ enum wl_seat_capability caps)+{+ if ((caps & WL_SEAT_CAPABILITY_POINTER) && !_glfw.wl.pointer)+ {+ _glfw.wl.pointer = wl_seat_get_pointer(seat);+ wl_pointer_add_listener(_glfw.wl.pointer, &pointerListener, NULL);+ }+ else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && _glfw.wl.pointer)+ {+ wl_pointer_destroy(_glfw.wl.pointer);+ _glfw.wl.pointer = NULL;+ }++ if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !_glfw.wl.keyboard)+ {+ _glfw.wl.keyboard = wl_seat_get_keyboard(seat);+ wl_keyboard_add_listener(_glfw.wl.keyboard, &keyboardListener, NULL);+ }+ else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && _glfw.wl.keyboard)+ {+ wl_keyboard_destroy(_glfw.wl.keyboard);+ _glfw.wl.keyboard = NULL;+ }+}++static void seatHandleName(void* userData,+ struct wl_seat* seat,+ const char* name)+{+}++static const struct wl_seat_listener seatListener =+{+ seatHandleCapabilities,+ seatHandleName,+};++static void dataOfferHandleOffer(void* userData,+ struct wl_data_offer* offer,+ const char* mimeType)+{+ for (unsigned int i = 0; i < _glfw.wl.offerCount; i++)+ {+ if (_glfw.wl.offers[i].offer == offer)+ {+ if (strcmp(mimeType, "text/plain;charset=utf-8") == 0)+ _glfw.wl.offers[i].text_plain_utf8 = GLFW_TRUE;+ else if (strcmp(mimeType, "text/uri-list") == 0)+ _glfw.wl.offers[i].text_uri_list = GLFW_TRUE;++ break;+ }+ }+}++static const struct wl_data_offer_listener dataOfferListener =+{+ dataOfferHandleOffer+};++static void dataDeviceHandleDataOffer(void* userData,+ struct wl_data_device* device,+ struct wl_data_offer* offer)+{+ _GLFWofferWayland* offers =+ _glfw_realloc(_glfw.wl.offers,+ sizeof(_GLFWofferWayland) * (_glfw.wl.offerCount + 1));+ if (!offers)+ {+ _glfwInputError(GLFW_OUT_OF_MEMORY, NULL);+ return;+ }++ _glfw.wl.offers = offers;+ _glfw.wl.offerCount++;++ _glfw.wl.offers[_glfw.wl.offerCount - 1] = (_GLFWofferWayland) { offer };+ wl_data_offer_add_listener(offer, &dataOfferListener, NULL);+}++static void dataDeviceHandleEnter(void* userData,+ struct wl_data_device* device,+ uint32_t serial,+ struct wl_surface* surface,+ wl_fixed_t x,+ wl_fixed_t y,+ struct wl_data_offer* offer)+{+ if (_glfw.wl.dragOffer)+ {+ wl_data_offer_destroy(_glfw.wl.dragOffer);+ _glfw.wl.dragOffer = NULL;+ _glfw.wl.dragFocus = NULL;+ }++ for (unsigned int i = 0; i < _glfw.wl.offerCount; i++)+ {+ if (_glfw.wl.offers[i].offer == offer)+ {+ _GLFWwindow* window = NULL;++ if (surface)+ {+ if (wl_proxy_get_tag((struct wl_proxy*) surface) == &_glfw.wl.tag)+ window = wl_surface_get_user_data(surface);+ }++ if (surface == window->wl.surface && _glfw.wl.offers[i].text_uri_list)+ {+ _glfw.wl.dragOffer = offer;+ _glfw.wl.dragFocus = window;+ _glfw.wl.dragSerial = serial;+ }++ _glfw.wl.offers[i] = _glfw.wl.offers[_glfw.wl.offerCount - 1];+ _glfw.wl.offerCount--;+ break;+ }+ }++ if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag)+ return;++ if (_glfw.wl.dragOffer)+ wl_data_offer_accept(offer, serial, "text/uri-list");+ else+ {+ wl_data_offer_accept(offer, serial, NULL);+ wl_data_offer_destroy(offer);+ }+}++static void dataDeviceHandleLeave(void* userData,+ struct wl_data_device* device)+{+ if (_glfw.wl.dragOffer)+ {+ wl_data_offer_destroy(_glfw.wl.dragOffer);+ _glfw.wl.dragOffer = NULL;+ _glfw.wl.dragFocus = NULL;+ }+}++static void dataDeviceHandleMotion(void* userData,+ struct wl_data_device* device,+ uint32_t time,+ wl_fixed_t x,+ wl_fixed_t y)+{+}++static void dataDeviceHandleDrop(void* userData,+ struct wl_data_device* device)+{+ if (!_glfw.wl.dragOffer)+ return;++ char* string = readDataOfferAsString(_glfw.wl.dragOffer, "text/uri-list");+ if (string)+ {+ int count;+ char** paths = _glfwParseUriList(string, &count);+ if (paths)+ _glfwInputDrop(_glfw.wl.dragFocus, count, (const char**) paths);++ for (int i = 0; i < count; i++)+ _glfw_free(paths[i]);++ _glfw_free(paths);+ }++ _glfw_free(string);+}++static void dataDeviceHandleSelection(void* userData,+ struct wl_data_device* device,+ struct wl_data_offer* offer)+{+ if (_glfw.wl.selectionOffer)+ {+ wl_data_offer_destroy(_glfw.wl.selectionOffer);+ _glfw.wl.selectionOffer = NULL;+ }++ for (unsigned int i = 0; i < _glfw.wl.offerCount; i++)+ {+ if (_glfw.wl.offers[i].offer == offer)+ {+ if (_glfw.wl.offers[i].text_plain_utf8)+ _glfw.wl.selectionOffer = offer;+ else+ wl_data_offer_destroy(offer);++ _glfw.wl.offers[i] = _glfw.wl.offers[_glfw.wl.offerCount - 1];+ _glfw.wl.offerCount--;+ break;+ }+ }+}++const struct wl_data_device_listener dataDeviceListener =+{+ dataDeviceHandleDataOffer,+ dataDeviceHandleEnter,+ dataDeviceHandleLeave,+ dataDeviceHandleMotion,+ dataDeviceHandleDrop,+ dataDeviceHandleSelection,+};++static void xdgActivationHandleDone(void* userData,+ struct xdg_activation_token_v1* activationToken,+ const char* token)+{+ _GLFWwindow* window = userData;++ if (activationToken != window->wl.activationToken)+ return;++ xdg_activation_v1_activate(_glfw.wl.activationManager, token, window->wl.surface);+ xdg_activation_token_v1_destroy(window->wl.activationToken);+ window->wl.activationToken = NULL;+}++static const struct xdg_activation_token_v1_listener xdgActivationListener =+{+ xdgActivationHandleDone+};++void _glfwAddSeatListenerWayland(struct wl_seat* seat)+{+ wl_seat_add_listener(seat, &seatListener, NULL);+}++void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device)+{+ wl_data_device_add_listener(device, &dataDeviceListener, NULL);+}+++//////////////////////////////////////////////////////////////////////////+////// GLFW platform API //////+//////////////////////////////////////////////////////////////////////////++GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window,+ const _GLFWwndconfig* wndconfig,+ const _GLFWctxconfig* ctxconfig,+ const _GLFWfbconfig* fbconfig)+{+ if (!createNativeSurface(window, wndconfig, fbconfig))+ return GLFW_FALSE;++ if (ctxconfig->client != GLFW_NO_API)+ {+ if (ctxconfig->source == GLFW_EGL_CONTEXT_API ||+ ctxconfig->source == GLFW_NATIVE_CONTEXT_API)+ {+ window->wl.egl.window = wl_egl_window_create(window->wl.surface,+ window->wl.fbWidth,+ window->wl.fbHeight);+ if (!window->wl.egl.window)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to create EGL window");+ return GLFW_FALSE;+ }++ if (!_glfwInitEGL())+ return GLFW_FALSE;+ if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))+ return GLFW_FALSE;+ }+ else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)+ {+ if (!_glfwInitOSMesa())+ return GLFW_FALSE;+ if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))+ return GLFW_FALSE;+ }++ if (!_glfwRefreshContextAttribs(window, ctxconfig))+ return GLFW_FALSE;+ }++ if (wndconfig->mousePassthrough)+ _glfwSetWindowMousePassthroughWayland(window, GLFW_TRUE);++ if (window->monitor || wndconfig->visible)+ {+ if (!createShellObjects(window))+ return GLFW_FALSE;+ }++ return GLFW_TRUE;+}++void _glfwDestroyWindowWayland(_GLFWwindow* window)+{+ if (window == _glfw.wl.pointerFocus)+ _glfw.wl.pointerFocus = NULL;++ if (window == _glfw.wl.keyboardFocus)+ _glfw.wl.keyboardFocus = NULL;++ if (window->wl.activationToken)+ xdg_activation_token_v1_destroy(window->wl.activationToken);++ if (window->wl.idleInhibitor)+ zwp_idle_inhibitor_v1_destroy(window->wl.idleInhibitor);++ if (window->wl.relativePointer)+ zwp_relative_pointer_v1_destroy(window->wl.relativePointer);++ if (window->wl.lockedPointer)+ zwp_locked_pointer_v1_destroy(window->wl.lockedPointer);++ if (window->wl.confinedPointer)+ zwp_confined_pointer_v1_destroy(window->wl.confinedPointer);++ if (window->context.destroy)+ window->context.destroy(window);++ destroyShellObjects(window);++ if (window->wl.fallback.buffer)+ wl_buffer_destroy(window->wl.fallback.buffer);++ if (window->wl.egl.window)+ wl_egl_window_destroy(window->wl.egl.window);++ if (window->wl.surface)+ wl_surface_destroy(window->wl.surface);++ _glfw_free(window->wl.appId);+ _glfw_free(window->wl.outputScales);+}++void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title)+{+ if (window->wl.libdecor.frame)+ libdecor_frame_set_title(window->wl.libdecor.frame, title);+ else if (window->wl.xdg.toplevel)+ xdg_toplevel_set_title(window->wl.xdg.toplevel, title);+}++void _glfwSetWindowIconWayland(_GLFWwindow* window,+ int count, const GLFWimage* images)+{+ _glfwInputError(GLFW_FEATURE_UNAVAILABLE,+ "Wayland: The platform does not support setting the window icon");+}++void _glfwGetWindowPosWayland(_GLFWwindow* window, int* xpos, int* ypos)+{+ // A Wayland client is not aware of its position, so just warn and leave it+ // as (0, 0)++ _glfwInputError(GLFW_FEATURE_UNAVAILABLE,+ "Wayland: The platform does not provide the window position");+}++void _glfwSetWindowPosWayland(_GLFWwindow* window, int xpos, int ypos)+{+ // A Wayland client can not set its position, so just warn++ _glfwInputError(GLFW_FEATURE_UNAVAILABLE,+ "Wayland: The platform does not support setting the window position");+}++void _glfwGetWindowSizeWayland(_GLFWwindow* window, int* width, int* height)+{+ if (width)+ *width = window->wl.width;+ if (height)+ *height = window->wl.height;+}++void _glfwSetWindowSizeWayland(_GLFWwindow* window, int width, int height)+{+ if (window->monitor)+ {+ // Video mode setting is not available on Wayland+ }+ else+ {+ if (!resizeWindow(window, width, height))+ return;++ if (window->wl.libdecor.frame)+ {+ struct libdecor_state* frameState =+ libdecor_state_new(window->wl.width, window->wl.height);+ libdecor_frame_commit(window->wl.libdecor.frame, frameState, NULL);+ libdecor_state_free(frameState);+ }++ if (window->wl.visible)+ _glfwInputWindowDamage(window);+ }+}++void _glfwSetWindowSizeLimitsWayland(_GLFWwindow* window,+ int minwidth, int minheight,+ int maxwidth, int maxheight)+{+ if (window->wl.libdecor.frame)+ {+ if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE)+ minwidth = minheight = 0;++ if (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE)+ maxwidth = maxheight = 0;++ libdecor_frame_set_min_content_size(window->wl.libdecor.frame,+ minwidth, minheight);+ libdecor_frame_set_max_content_size(window->wl.libdecor.frame,+ maxwidth, maxheight);+ }+ else if (window->wl.xdg.toplevel)+ updateXdgSizeLimits(window);+}++void _glfwSetWindowAspectRatioWayland(_GLFWwindow* window, int numer, int denom)+{+ if (window->wl.maximized || window->wl.fullscreen)+ return;++ int width = window->wl.width, height = window->wl.height;++ if (numer != GLFW_DONT_CARE && denom != GLFW_DONT_CARE)+ {+ const float aspectRatio = (float) width / (float) height;+ const float targetRatio = (float) numer / (float) denom;+ if (aspectRatio < targetRatio)+ height /= targetRatio;+ else if (aspectRatio > targetRatio)+ width *= targetRatio;+ }++ if (resizeWindow(window, width, height))+ {+ if (window->wl.libdecor.frame)+ {+ struct libdecor_state* frameState =+ libdecor_state_new(window->wl.width, window->wl.height);+ libdecor_frame_commit(window->wl.libdecor.frame, frameState, NULL);+ libdecor_state_free(frameState);+ }++ _glfwInputWindowSize(window, window->wl.width, window->wl.height);++ if (window->wl.visible)+ _glfwInputWindowDamage(window);+ }+}++void _glfwGetFramebufferSizeWayland(_GLFWwindow* window, int* width, int* height)+{+ if (width)+ *width = window->wl.fbWidth;+ if (height)+ *height = window->wl.fbHeight;+}++void _glfwGetWindowFrameSizeWayland(_GLFWwindow* window,+ int* left, int* top,+ int* right, int* bottom)+{+ if (window->wl.fallback.decorations)+ {+ if (top)+ *top = GLFW_CAPTION_HEIGHT;+ if (left)+ *left = GLFW_BORDER_SIZE;+ if (right)+ *right = GLFW_BORDER_SIZE;+ if (bottom)+ *bottom = GLFW_BORDER_SIZE;+ }+}++void _glfwGetWindowContentScaleWayland(_GLFWwindow* window,+ float* xscale, float* yscale)+{+ if (window->wl.fractionalScale)+ {+ if (xscale)+ *xscale = (float) window->wl.scalingNumerator / 120.f;+ if (yscale)+ *yscale = (float) window->wl.scalingNumerator / 120.f;+ }+ else+ {+ if (xscale)+ *xscale = (float) window->wl.bufferScale;+ if (yscale)+ *yscale = (float) window->wl.bufferScale;+ }+}++void _glfwIconifyWindowWayland(_GLFWwindow* window)+{+ if (window->wl.libdecor.frame)+ libdecor_frame_set_minimized(window->wl.libdecor.frame);+ else if (window->wl.xdg.toplevel)+ xdg_toplevel_set_minimized(window->wl.xdg.toplevel);+}++void _glfwRestoreWindowWayland(_GLFWwindow* window)+{+ if (window->monitor)+ {+ // There is no way to unset minimized, or even to know if we are+ // minimized, so there is nothing to do in this case.+ }+ else+ {+ // We assume we are not minimized and act only on maximization++ if (window->wl.maximized)+ {+ if (window->wl.libdecor.frame)+ libdecor_frame_unset_maximized(window->wl.libdecor.frame);+ else if (window->wl.xdg.toplevel)+ xdg_toplevel_unset_maximized(window->wl.xdg.toplevel);+ else+ window->wl.maximized = GLFW_FALSE;+ }+ }+}++void _glfwMaximizeWindowWayland(_GLFWwindow* window)+{+ if (window->wl.libdecor.frame)+ libdecor_frame_set_maximized(window->wl.libdecor.frame);+ else if (window->wl.xdg.toplevel)+ xdg_toplevel_set_maximized(window->wl.xdg.toplevel);+ else+ window->wl.maximized = GLFW_TRUE;+}++void _glfwShowWindowWayland(_GLFWwindow* window)+{+ if (!window->wl.libdecor.frame && !window->wl.xdg.toplevel)+ {+ // NOTE: The XDG surface and role are created here so command-line applications+ // with off-screen windows do not appear in for example the Unity dock+ createShellObjects(window);+ }+}++void _glfwHideWindowWayland(_GLFWwindow* window)+{+ if (window->wl.visible)+ {+ window->wl.visible = GLFW_FALSE;+ destroyShellObjects(window);++ wl_surface_attach(window->wl.surface, NULL, 0, 0);+ wl_surface_commit(window->wl.surface);+ }+}++void _glfwRequestWindowAttentionWayland(_GLFWwindow* window)+{+ if (!_glfw.wl.activationManager)+ return;++ // We're about to overwrite this with a new request+ if (window->wl.activationToken)+ xdg_activation_token_v1_destroy(window->wl.activationToken);++ window->wl.activationToken =+ xdg_activation_v1_get_activation_token(_glfw.wl.activationManager);+ xdg_activation_token_v1_add_listener(window->wl.activationToken,+ &xdgActivationListener,+ window);++ xdg_activation_token_v1_commit(window->wl.activationToken);+}++void _glfwFocusWindowWayland(_GLFWwindow* window)+{+ if (!_glfw.wl.activationManager)+ return;++ if (window->wl.activationToken)+ xdg_activation_token_v1_destroy(window->wl.activationToken);++ window->wl.activationToken =+ xdg_activation_v1_get_activation_token(_glfw.wl.activationManager);+ xdg_activation_token_v1_add_listener(window->wl.activationToken,+ &xdgActivationListener,+ window);++ xdg_activation_token_v1_set_serial(window->wl.activationToken,+ _glfw.wl.serial,+ _glfw.wl.seat);++ _GLFWwindow* requester = _glfw.wl.keyboardFocus;+ if (requester)+ {+ xdg_activation_token_v1_set_surface(window->wl.activationToken,+ requester->wl.surface);++ if (requester->wl.appId)+ {+ xdg_activation_token_v1_set_app_id(window->wl.activationToken,+ requester->wl.appId);+ }+ }++ xdg_activation_token_v1_commit(window->wl.activationToken);+}++void _glfwSetWindowMonitorWayland(_GLFWwindow* window,+ _GLFWmonitor* monitor,+ int xpos, int ypos,+ int width, int height,+ int refreshRate)+{+ if (window->monitor == monitor)+ {+ if (!monitor)+ _glfwSetWindowSizeWayland(window, width, height);++ return;+ }++ if (window->monitor)+ releaseMonitorWayland(window);++ _glfwInputWindowMonitor(window, monitor);++ if (window->monitor)+ acquireMonitorWayland(window);+ else+ _glfwSetWindowSizeWayland(window, width, height);+}++GLFWbool _glfwWindowFocusedWayland(_GLFWwindow* window)+{+ return _glfw.wl.keyboardFocus == window;+}++GLFWbool _glfwWindowIconifiedWayland(_GLFWwindow* window)+{+ // xdg-shell doesn’t give any way to request whether a surface is+ // iconified.+ return GLFW_FALSE;+}++GLFWbool _glfwWindowVisibleWayland(_GLFWwindow* window)+{+ return window->wl.visible;+}++GLFWbool _glfwWindowMaximizedWayland(_GLFWwindow* window)+{+ return window->wl.maximized;+}++GLFWbool _glfwWindowHoveredWayland(_GLFWwindow* window)+{+ return window->wl.hovered;+}++GLFWbool _glfwFramebufferTransparentWayland(_GLFWwindow* window)+{+ return window->wl.transparent;+}++void _glfwSetWindowResizableWayland(_GLFWwindow* window, GLFWbool enabled)+{+ if (window->wl.libdecor.frame)+ {+ if (enabled)+ {+ libdecor_frame_set_capabilities(window->wl.libdecor.frame,+ LIBDECOR_ACTION_RESIZE);+ }+ else+ {+ libdecor_frame_unset_capabilities(window->wl.libdecor.frame,+ LIBDECOR_ACTION_RESIZE);+ }+ }+ else if (window->wl.xdg.toplevel)+ updateXdgSizeLimits(window);+}++void _glfwSetWindowDecoratedWayland(_GLFWwindow* window, GLFWbool enabled)+{+ if (window->wl.libdecor.frame)+ {+ libdecor_frame_set_visibility(window->wl.libdecor.frame, enabled);+ }+ else if (window->wl.xdg.decoration)+ {+ uint32_t mode;++ if (enabled)+ mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE;+ else+ mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;++ zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode);+ }+ else if (window->wl.xdg.toplevel)+ {+ if (enabled)+ createFallbackDecorations(window);+ else+ destroyFallbackDecorations(window);+ }+}++void _glfwSetWindowFloatingWayland(_GLFWwindow* window, GLFWbool enabled)+{+ _glfwInputError(GLFW_FEATURE_UNAVAILABLE,+ "Wayland: Platform does not support making a window floating");+}++void _glfwSetWindowMousePassthroughWayland(_GLFWwindow* window, GLFWbool enabled)+{+ if (enabled)+ {+ struct wl_region* region = wl_compositor_create_region(_glfw.wl.compositor);+ wl_surface_set_input_region(window->wl.surface, region);+ wl_region_destroy(region);+ }+ else+ wl_surface_set_input_region(window->wl.surface, NULL);+}++float _glfwGetWindowOpacityWayland(_GLFWwindow* window)+{+ return 1.f;+}++void _glfwSetWindowOpacityWayland(_GLFWwindow* window, float opacity)+{+ _glfwInputError(GLFW_FEATURE_UNAVAILABLE,+ "Wayland: The platform does not support setting the window opacity");+}++void _glfwSetRawMouseMotionWayland(_GLFWwindow* window, GLFWbool enabled)+{+ // This is handled in relativePointerHandleRelativeMotion+}++GLFWbool _glfwRawMouseMotionSupportedWayland(void)+{+ return GLFW_TRUE;+}++void _glfwPollEventsWayland(void)+{+ double timeout = 0.0;+ handleEvents(&timeout);+}++void _glfwWaitEventsWayland(void)+{+ handleEvents(NULL);+}++void _glfwWaitEventsTimeoutWayland(double timeout)+{+ handleEvents(&timeout);+}++void _glfwPostEmptyEventWayland(void)+{+ wl_display_sync(_glfw.wl.display);+ flushDisplay();+}++void _glfwGetCursorPosWayland(_GLFWwindow* window, double* xpos, double* ypos)+{+ if (xpos)+ *xpos = window->wl.cursorPosX;+ if (ypos)+ *ypos = window->wl.cursorPosY;+}++void _glfwSetCursorPosWayland(_GLFWwindow* window, double x, double y)+{+ _glfwInputError(GLFW_FEATURE_UNAVAILABLE,+ "Wayland: The platform does not support setting the cursor position");+}++void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode)+{+ _glfwSetCursorWayland(window, window->wl.currentCursor);+}++const char* _glfwGetScancodeNameWayland(int scancode)+{+ if (scancode < 0 || scancode > 255)+ {+ _glfwInputError(GLFW_INVALID_VALUE,+ "Wayland: Invalid scancode %i",+ scancode);+ return NULL;+ }++ const int key = _glfw.wl.keycodes[scancode];+ if (key == GLFW_KEY_UNKNOWN)+ return NULL;++ const xkb_keycode_t keycode = scancode + 8;+ const xkb_layout_index_t layout =+ xkb_state_key_get_layout(_glfw.wl.xkb.state, keycode);+ if (layout == XKB_LAYOUT_INVALID)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to retrieve layout for key name");+ return NULL;+ }++ const xkb_keysym_t* keysyms = NULL;+ xkb_keymap_key_get_syms_by_level(_glfw.wl.xkb.keymap,+ keycode,+ layout,+ 0,+ &keysyms);+ if (keysyms == NULL)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to retrieve keysym for key name");+ return NULL;+ }++ const uint32_t codepoint = _glfwKeySym2Unicode(keysyms[0]);+ if (codepoint == GLFW_INVALID_CODEPOINT)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to retrieve codepoint for key name");+ return NULL;+ }++ const size_t count = _glfwEncodeUTF8(_glfw.wl.keynames[key], codepoint);+ if (count == 0)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to encode codepoint for key name");+ return NULL;+ }++ _glfw.wl.keynames[key][count] = '\0';+ return _glfw.wl.keynames[key];+}++int _glfwGetKeyScancodeWayland(int key)+{+ return _glfw.wl.scancodes[key];+}++GLFWbool _glfwCreateCursorWayland(_GLFWcursor* cursor,+ const GLFWimage* image,+ int xhot, int yhot)+{+ cursor->wl.buffer = createShmBuffer(image);+ if (!cursor->wl.buffer)+ return GLFW_FALSE;++ cursor->wl.width = image->width;+ cursor->wl.height = image->height;+ cursor->wl.xhot = xhot;+ cursor->wl.yhot = yhot;+ return GLFW_TRUE;+}++GLFWbool _glfwCreateStandardCursorWayland(_GLFWcursor* cursor, int shape)+{+ const char* name = NULL;++ // Try the XDG names first+ switch (shape)+ {+ case GLFW_ARROW_CURSOR:+ name = "default";+ break;+ case GLFW_IBEAM_CURSOR:+ name = "text";+ break;+ case GLFW_CROSSHAIR_CURSOR:+ name = "crosshair";+ break;+ case GLFW_POINTING_HAND_CURSOR:+ name = "pointer";+ break;+ case GLFW_RESIZE_EW_CURSOR:+ name = "ew-resize";+ break;+ case GLFW_RESIZE_NS_CURSOR:+ name = "ns-resize";+ break;+ case GLFW_RESIZE_NWSE_CURSOR:+ name = "nwse-resize";+ break;+ case GLFW_RESIZE_NESW_CURSOR:+ name = "nesw-resize";+ break;+ case GLFW_RESIZE_ALL_CURSOR:+ name = "all-scroll";+ break;+ case GLFW_NOT_ALLOWED_CURSOR:+ name = "not-allowed";+ break;+ }++ cursor->wl.cursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, name);++ if (_glfw.wl.cursorThemeHiDPI)+ {+ cursor->wl.cursorHiDPI =+ wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI, name);+ }++ if (!cursor->wl.cursor)+ {+ // Fall back to the core X11 names+ switch (shape)+ {+ case GLFW_ARROW_CURSOR:+ name = "left_ptr";+ break;+ case GLFW_IBEAM_CURSOR:+ name = "xterm";+ break;+ case GLFW_CROSSHAIR_CURSOR:+ name = "crosshair";+ break;+ case GLFW_POINTING_HAND_CURSOR:+ name = "hand2";+ break;+ case GLFW_RESIZE_EW_CURSOR:+ name = "sb_h_double_arrow";+ break;+ case GLFW_RESIZE_NS_CURSOR:+ name = "sb_v_double_arrow";+ break;+ case GLFW_RESIZE_ALL_CURSOR:+ name = "fleur";+ break;+ default:+ _glfwInputError(GLFW_CURSOR_UNAVAILABLE,+ "Wayland: Standard cursor shape unavailable");+ return GLFW_FALSE;+ }++ cursor->wl.cursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, name);+ if (!cursor->wl.cursor)+ {+ _glfwInputError(GLFW_CURSOR_UNAVAILABLE,+ "Wayland: Failed to create standard cursor \"%s\"",+ name);+ return GLFW_FALSE;+ }++ if (_glfw.wl.cursorThemeHiDPI)+ {+ if (!cursor->wl.cursorHiDPI)+ {+ cursor->wl.cursorHiDPI =+ wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI, name);+ }+ }+ }++ return GLFW_TRUE;+}++void _glfwDestroyCursorWayland(_GLFWcursor* cursor)+{+ // If it's a standard cursor we don't need to do anything here+ if (cursor->wl.cursor)+ return;++ if (cursor->wl.buffer)+ wl_buffer_destroy(cursor->wl.buffer);+}++static void relativePointerHandleRelativeMotion(void* userData,+ struct zwp_relative_pointer_v1* pointer,+ uint32_t timeHi,+ uint32_t timeLo,+ wl_fixed_t dx,+ wl_fixed_t dy,+ wl_fixed_t dxUnaccel,+ wl_fixed_t dyUnaccel)+{+ _GLFWwindow* window = userData;+ double xpos = window->virtualCursorPosX;+ double ypos = window->virtualCursorPosY;++ if (window->cursorMode != GLFW_CURSOR_DISABLED)+ return;++ if (window->rawMouseMotion)+ {+ xpos += wl_fixed_to_double(dxUnaccel);+ ypos += wl_fixed_to_double(dyUnaccel);+ }+ else+ {+ xpos += wl_fixed_to_double(dx);+ ypos += wl_fixed_to_double(dy);+ }++ _glfwInputCursorPos(window, xpos, ypos);+}++static const struct zwp_relative_pointer_v1_listener relativePointerListener =+{+ relativePointerHandleRelativeMotion+};++static void lockedPointerHandleLocked(void* userData,+ struct zwp_locked_pointer_v1* lockedPointer)+{+}++static void lockedPointerHandleUnlocked(void* userData,+ struct zwp_locked_pointer_v1* lockedPointer)+{+}++static const struct zwp_locked_pointer_v1_listener lockedPointerListener =+{+ lockedPointerHandleLocked,+ lockedPointerHandleUnlocked+};++static void lockPointer(_GLFWwindow* window)+{+ if (!_glfw.wl.relativePointerManager)+ {+ _glfwInputError(GLFW_FEATURE_UNAVAILABLE,+ "Wayland: The compositor does not support pointer locking");+ return;+ }++ window->wl.relativePointer =+ zwp_relative_pointer_manager_v1_get_relative_pointer(+ _glfw.wl.relativePointerManager,+ _glfw.wl.pointer);+ zwp_relative_pointer_v1_add_listener(window->wl.relativePointer,+ &relativePointerListener,+ window);++ window->wl.lockedPointer =+ zwp_pointer_constraints_v1_lock_pointer(+ _glfw.wl.pointerConstraints,+ window->wl.surface,+ _glfw.wl.pointer,+ NULL,+ ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);+ zwp_locked_pointer_v1_add_listener(window->wl.lockedPointer,+ &lockedPointerListener,+ window);+}++static void unlockPointer(_GLFWwindow* window)+{+ zwp_relative_pointer_v1_destroy(window->wl.relativePointer);+ window->wl.relativePointer = NULL;++ zwp_locked_pointer_v1_destroy(window->wl.lockedPointer);+ window->wl.lockedPointer = NULL;+}++static void confinedPointerHandleConfined(void* userData,+ struct zwp_confined_pointer_v1* confinedPointer)+{+}++static void confinedPointerHandleUnconfined(void* userData,+ struct zwp_confined_pointer_v1* confinedPointer)+{+}++static const struct zwp_confined_pointer_v1_listener confinedPointerListener =+{+ confinedPointerHandleConfined,+ confinedPointerHandleUnconfined+};++static void confinePointer(_GLFWwindow* window)+{+ window->wl.confinedPointer =+ zwp_pointer_constraints_v1_confine_pointer(+ _glfw.wl.pointerConstraints,+ window->wl.surface,+ _glfw.wl.pointer,+ NULL,+ ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);++ zwp_confined_pointer_v1_add_listener(window->wl.confinedPointer,+ &confinedPointerListener,+ window);+}++static void unconfinePointer(_GLFWwindow* window)+{+ zwp_confined_pointer_v1_destroy(window->wl.confinedPointer);+ window->wl.confinedPointer = NULL;+}++void _glfwSetCursorWayland(_GLFWwindow* window, _GLFWcursor* cursor)+{+ if (!_glfw.wl.pointer)+ return;++ window->wl.currentCursor = cursor;++ // If we're not in the correct window just save the cursor+ // the next time the pointer enters the window the cursor will change+ if (!window->wl.hovered)+ return;++ // Update pointer lock to match cursor mode+ if (window->cursorMode == GLFW_CURSOR_DISABLED)+ {+ if (window->wl.confinedPointer)+ unconfinePointer(window);+ if (!window->wl.lockedPointer)+ lockPointer(window);+ }+ else if (window->cursorMode == GLFW_CURSOR_CAPTURED)+ {+ if (window->wl.lockedPointer)+ unlockPointer(window);+ if (!window->wl.confinedPointer)+ confinePointer(window);+ }+ else if (window->cursorMode == GLFW_CURSOR_NORMAL ||+ window->cursorMode == GLFW_CURSOR_HIDDEN)+ {+ if (window->wl.lockedPointer)+ unlockPointer(window);+ else if (window->wl.confinedPointer)+ unconfinePointer(window);+ }++ if (window->cursorMode == GLFW_CURSOR_NORMAL ||+ window->cursorMode == GLFW_CURSOR_CAPTURED)+ {+ if (cursor)+ setCursorImage(window, &cursor->wl);+ else+ {+ struct wl_cursor* defaultCursor =+ wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, "left_ptr");+ if (!defaultCursor)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Standard cursor not found");+ return;+ }++ struct wl_cursor* defaultCursorHiDPI = NULL;+ if (_glfw.wl.cursorThemeHiDPI)+ {+ defaultCursorHiDPI =+ wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI, "left_ptr");+ }++ _GLFWcursorWayland cursorWayland =+ {+ defaultCursor,+ defaultCursorHiDPI,+ NULL,+ 0, 0,+ 0, 0,+ 0+ };++ setCursorImage(window, &cursorWayland);+ }+ }+ else if (window->cursorMode == GLFW_CURSOR_HIDDEN ||+ window->cursorMode == GLFW_CURSOR_DISABLED)+ {+ wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, NULL, 0, 0);+ }+}++static void dataSourceHandleTarget(void* userData,+ struct wl_data_source* source,+ const char* mimeType)+{+ if (_glfw.wl.selectionSource != source)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Unknown clipboard data source");+ return;+ }+}++static void dataSourceHandleSend(void* userData,+ struct wl_data_source* source,+ const char* mimeType,+ int fd)+{+ // Ignore it if this is an outdated or invalid request+ if (_glfw.wl.selectionSource != source ||+ strcmp(mimeType, "text/plain;charset=utf-8") != 0)+ {+ close(fd);+ return;+ }++ char* string = _glfw.wl.clipboardString;+ size_t length = strlen(string);++ while (length > 0)+ {+ const ssize_t result = write(fd, string, length);+ if (result == -1)+ {+ if (errno == EINTR)+ continue;++ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Error while writing the clipboard: %s",+ strerror(errno));+ break;+ }++ length -= result;+ string += result;+ }++ close(fd);+}++static void dataSourceHandleCancelled(void* userData,+ struct wl_data_source* source)+{+ wl_data_source_destroy(source);++ if (_glfw.wl.selectionSource != source)+ return;++ _glfw.wl.selectionSource = NULL;+}++static const struct wl_data_source_listener dataSourceListener =+{+ dataSourceHandleTarget,+ dataSourceHandleSend,+ dataSourceHandleCancelled,+};++void _glfwSetClipboardStringWayland(const char* string)+{+ if (_glfw.wl.selectionSource)+ {+ wl_data_source_destroy(_glfw.wl.selectionSource);+ _glfw.wl.selectionSource = NULL;+ }++ char* copy = _glfw_strdup(string);+ if (!copy)+ {+ _glfwInputError(GLFW_OUT_OF_MEMORY, NULL);+ return;+ }++ _glfw_free(_glfw.wl.clipboardString);+ _glfw.wl.clipboardString = copy;++ _glfw.wl.selectionSource =+ wl_data_device_manager_create_data_source(_glfw.wl.dataDeviceManager);+ if (!_glfw.wl.selectionSource)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to create clipboard data source");+ return;+ }+ wl_data_source_add_listener(_glfw.wl.selectionSource,+ &dataSourceListener,+ NULL);+ wl_data_source_offer(_glfw.wl.selectionSource, "text/plain;charset=utf-8");+ wl_data_device_set_selection(_glfw.wl.dataDevice,+ _glfw.wl.selectionSource,+ _glfw.wl.serial);+}++const char* _glfwGetClipboardStringWayland(void)+{+ if (!_glfw.wl.selectionOffer)+ {+ _glfwInputError(GLFW_FORMAT_UNAVAILABLE,+ "Wayland: No clipboard data available");+ return NULL;+ }++ if (_glfw.wl.selectionSource)+ return _glfw.wl.clipboardString;++ _glfw_free(_glfw.wl.clipboardString);+ _glfw.wl.clipboardString =+ readDataOfferAsString(_glfw.wl.selectionOffer, "text/plain;charset=utf-8");+ return _glfw.wl.clipboardString;+}++EGLenum _glfwGetEGLPlatformWayland(EGLint** attribs)+{+ if (_glfw.egl.EXT_platform_base && _glfw.egl.EXT_platform_wayland)+ return EGL_PLATFORM_WAYLAND_EXT;+ else+ return 0;+}++EGLNativeDisplayType _glfwGetEGLNativeDisplayWayland(void)+{+ return _glfw.wl.display;+}++EGLNativeWindowType _glfwGetEGLNativeWindowWayland(_GLFWwindow* window)+{+ return window->wl.egl.window;+}++void _glfwGetRequiredInstanceExtensionsWayland(char** extensions)+{+ if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_wayland_surface)+ return;++ extensions[0] = "VK_KHR_surface";+ extensions[1] = "VK_KHR_wayland_surface";+}++GLFWbool _glfwGetPhysicalDevicePresentationSupportWayland(VkInstance instance,+ VkPhysicalDevice device,+ uint32_t queuefamily)+{+ PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR+ vkGetPhysicalDeviceWaylandPresentationSupportKHR =+ (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)+ vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");+ if (!vkGetPhysicalDeviceWaylandPresentationSupportKHR)+ {+ _glfwInputError(GLFW_API_UNAVAILABLE,+ "Wayland: Vulkan instance missing VK_KHR_wayland_surface extension");+ return VK_NULL_HANDLE;+ }++ return vkGetPhysicalDeviceWaylandPresentationSupportKHR(device,+ queuefamily,+ _glfw.wl.display);+}++VkResult _glfwCreateWindowSurfaceWayland(VkInstance instance,+ _GLFWwindow* window,+ const VkAllocationCallbacks* allocator,+ VkSurfaceKHR* surface)+{+ VkResult err;+ VkWaylandSurfaceCreateInfoKHR sci;+ PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;++ vkCreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR)+ vkGetInstanceProcAddr(instance, "vkCreateWaylandSurfaceKHR");+ if (!vkCreateWaylandSurfaceKHR)+ {+ _glfwInputError(GLFW_API_UNAVAILABLE,+ "Wayland: Vulkan instance missing VK_KHR_wayland_surface extension");+ return VK_ERROR_EXTENSION_NOT_PRESENT;+ }++ memset(&sci, 0, sizeof(sci));+ sci.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;+ sci.display = _glfw.wl.display;+ sci.surface = window->wl.surface;++ err = vkCreateWaylandSurfaceKHR(instance, &sci, allocator, surface);+ if (err)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR,+ "Wayland: Failed to create Vulkan surface: %s",+ _glfwGetVulkanResultString(err));+ }++ return err;+}+++//////////////////////////////////////////////////////////////////////////+////// GLFW native API //////+//////////////////////////////////////////////////////////////////////////++GLFWAPI struct wl_display* glfwGetWaylandDisplay(void)+{+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);++ if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND)+ {+ _glfwInputError(GLFW_PLATFORM_UNAVAILABLE,+ "Wayland: Platform not initialized");+ return NULL;+ }++ return _glfw.wl.display;+}++GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle)+{+ _GLFWwindow* window = (_GLFWwindow*) handle;+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);++ if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND)+ {+ _glfwInputError(GLFW_PLATFORM_UNAVAILABLE,+ "Wayland: Platform not initialized");+ return NULL;+ }++ return window->wl.surface;+}++#endif // _GLFW_WAYLAND
raylib/src/external/glfw/src/x11_init.c view
@@ -1,8 +1,9 @@ //========================================================================-// GLFW 3.4 X11 - www.glfw.org+// GLFW 3.4 X11 (modified for raylib) - www.glfw.org; www.raylib.com //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>+// Copyright (c) 2024 M374LX <wilsalx@gmail.com> // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages@@ -24,11 +25,11 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" +#if defined(_GLFW_X11)+ #include <stdlib.h> #include <string.h> #include <limits.h>@@ -210,7 +211,7 @@ // Create key code translation tables //-static void createKeyTables(void)+static void createKeyTablesX11(void) { int scancodeMin, scancodeMax; @@ -908,7 +909,7 @@ // Update the key code LUT // FIXME: We should listen to XkbMapNotify events to track changes to // the keyboard mapping.- createKeyTables();+ createKeyTablesX11(); // String format atoms _glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);@@ -1166,86 +1167,86 @@ { const _GLFWplatform x11 = {- GLFW_PLATFORM_X11,- _glfwInitX11,- _glfwTerminateX11,- _glfwGetCursorPosX11,- _glfwSetCursorPosX11,- _glfwSetCursorModeX11,- _glfwSetRawMouseMotionX11,- _glfwRawMouseMotionSupportedX11,- _glfwCreateCursorX11,- _glfwCreateStandardCursorX11,- _glfwDestroyCursorX11,- _glfwSetCursorX11,- _glfwGetScancodeNameX11,- _glfwGetKeyScancodeX11,- _glfwSetClipboardStringX11,- _glfwGetClipboardStringX11,-#if defined(__linux__)- _glfwInitJoysticksLinux,- _glfwTerminateJoysticksLinux,- _glfwPollJoystickLinux,- _glfwGetMappingNameLinux,- _glfwUpdateGamepadGUIDLinux,+ .platformID = GLFW_PLATFORM_X11,+ .init = _glfwInitX11,+ .terminate = _glfwTerminateX11,+ .getCursorPos = _glfwGetCursorPosX11,+ .setCursorPos = _glfwSetCursorPosX11,+ .setCursorMode = _glfwSetCursorModeX11,+ .setRawMouseMotion = _glfwSetRawMouseMotionX11,+ .rawMouseMotionSupported = _glfwRawMouseMotionSupportedX11,+ .createCursor = _glfwCreateCursorX11,+ .createStandardCursor = _glfwCreateStandardCursorX11,+ .destroyCursor = _glfwDestroyCursorX11,+ .setCursor = _glfwSetCursorX11,+ .getScancodeName = _glfwGetScancodeNameX11,+ .getKeyScancode = _glfwGetKeyScancodeX11,+ .setClipboardString = _glfwSetClipboardStringX11,+ .getClipboardString = _glfwGetClipboardStringX11,+#if defined(GLFW_BUILD_LINUX_JOYSTICK)+ .initJoysticks = _glfwInitJoysticksLinux,+ .terminateJoysticks = _glfwTerminateJoysticksLinux,+ .pollJoystick = _glfwPollJoystickLinux,+ .getMappingName = _glfwGetMappingNameLinux,+ .updateGamepadGUID = _glfwUpdateGamepadGUIDLinux, #else- _glfwInitJoysticksNull,- _glfwTerminateJoysticksNull,- _glfwPollJoystickNull,- _glfwGetMappingNameNull,- _glfwUpdateGamepadGUIDNull,+ .initJoysticks = _glfwInitJoysticksNull,+ .terminateJoysticks = _glfwTerminateJoysticksNull,+ .pollJoystick = _glfwPollJoystickNull,+ .getMappingName = _glfwGetMappingNameNull,+ .updateGamepadGUID = _glfwUpdateGamepadGUIDNull, #endif- _glfwFreeMonitorX11,- _glfwGetMonitorPosX11,- _glfwGetMonitorContentScaleX11,- _glfwGetMonitorWorkareaX11,- _glfwGetVideoModesX11,- _glfwGetVideoModeX11,- _glfwGetGammaRampX11,- _glfwSetGammaRampX11,- _glfwCreateWindowX11,- _glfwDestroyWindowX11,- _glfwSetWindowTitleX11,- _glfwSetWindowIconX11,- _glfwGetWindowPosX11,- _glfwSetWindowPosX11,- _glfwGetWindowSizeX11,- _glfwSetWindowSizeX11,- _glfwSetWindowSizeLimitsX11,- _glfwSetWindowAspectRatioX11,- _glfwGetFramebufferSizeX11,- _glfwGetWindowFrameSizeX11,- _glfwGetWindowContentScaleX11,- _glfwIconifyWindowX11,- _glfwRestoreWindowX11,- _glfwMaximizeWindowX11,- _glfwShowWindowX11,- _glfwHideWindowX11,- _glfwRequestWindowAttentionX11,- _glfwFocusWindowX11,- _glfwSetWindowMonitorX11,- _glfwWindowFocusedX11,- _glfwWindowIconifiedX11,- _glfwWindowVisibleX11,- _glfwWindowMaximizedX11,- _glfwWindowHoveredX11,- _glfwFramebufferTransparentX11,- _glfwGetWindowOpacityX11,- _glfwSetWindowResizableX11,- _glfwSetWindowDecoratedX11,- _glfwSetWindowFloatingX11,- _glfwSetWindowOpacityX11,- _glfwSetWindowMousePassthroughX11,- _glfwPollEventsX11,- _glfwWaitEventsX11,- _glfwWaitEventsTimeoutX11,- _glfwPostEmptyEventX11,- _glfwGetEGLPlatformX11,- _glfwGetEGLNativeDisplayX11,- _glfwGetEGLNativeWindowX11,- _glfwGetRequiredInstanceExtensionsX11,- _glfwGetPhysicalDevicePresentationSupportX11,- _glfwCreateWindowSurfaceX11,+ .freeMonitor = _glfwFreeMonitorX11,+ .getMonitorPos = _glfwGetMonitorPosX11,+ .getMonitorContentScale = _glfwGetMonitorContentScaleX11,+ .getMonitorWorkarea = _glfwGetMonitorWorkareaX11,+ .getVideoModes = _glfwGetVideoModesX11,+ .getVideoMode = _glfwGetVideoModeX11,+ .getGammaRamp = _glfwGetGammaRampX11,+ .setGammaRamp = _glfwSetGammaRampX11,+ .createWindow = _glfwCreateWindowX11,+ .destroyWindow = _glfwDestroyWindowX11,+ .setWindowTitle = _glfwSetWindowTitleX11,+ .setWindowIcon = _glfwSetWindowIconX11,+ .getWindowPos = _glfwGetWindowPosX11,+ .setWindowPos = _glfwSetWindowPosX11,+ .getWindowSize = _glfwGetWindowSizeX11,+ .setWindowSize = _glfwSetWindowSizeX11,+ .setWindowSizeLimits = _glfwSetWindowSizeLimitsX11,+ .setWindowAspectRatio = _glfwSetWindowAspectRatioX11,+ .getFramebufferSize = _glfwGetFramebufferSizeX11,+ .getWindowFrameSize = _glfwGetWindowFrameSizeX11,+ .getWindowContentScale = _glfwGetWindowContentScaleX11,+ .iconifyWindow = _glfwIconifyWindowX11,+ .restoreWindow = _glfwRestoreWindowX11,+ .maximizeWindow = _glfwMaximizeWindowX11,+ .showWindow = _glfwShowWindowX11,+ .hideWindow = _glfwHideWindowX11,+ .requestWindowAttention = _glfwRequestWindowAttentionX11,+ .focusWindow = _glfwFocusWindowX11,+ .setWindowMonitor = _glfwSetWindowMonitorX11,+ .windowFocused = _glfwWindowFocusedX11,+ .windowIconified = _glfwWindowIconifiedX11,+ .windowVisible = _glfwWindowVisibleX11,+ .windowMaximized = _glfwWindowMaximizedX11,+ .windowHovered = _glfwWindowHoveredX11,+ .framebufferTransparent = _glfwFramebufferTransparentX11,+ .getWindowOpacity = _glfwGetWindowOpacityX11,+ .setWindowResizable = _glfwSetWindowResizableX11,+ .setWindowDecorated = _glfwSetWindowDecoratedX11,+ .setWindowFloating = _glfwSetWindowFloatingX11,+ .setWindowOpacity = _glfwSetWindowOpacityX11,+ .setWindowMousePassthrough = _glfwSetWindowMousePassthroughX11,+ .pollEvents = _glfwPollEventsX11,+ .waitEvents = _glfwWaitEventsX11,+ .waitEventsTimeout = _glfwWaitEventsTimeoutX11,+ .postEmptyEvent = _glfwPostEmptyEventX11,+ .getEGLPlatform = _glfwGetEGLPlatformX11,+ .getEGLNativeDisplay = _glfwGetEGLNativeDisplayX11,+ .getEGLNativeWindow = _glfwGetEGLNativeWindowX11,+ .getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsX11,+ .getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportX11,+ .createWindowSurface = _glfwCreateWindowSurfaceX11 }; // HACK: If the application has left the locale as "C" then both wide@@ -1651,4 +1652,6 @@ close(_glfw.x11.emptyEventPipe[1]); } }++#endif // _GLFW_X11
raylib/src/external/glfw/src/x11_monitor.c view
@@ -24,11 +24,11 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" +#if defined(_GLFW_X11)+ #include <limits.h> #include <stdlib.h> #include <string.h>@@ -491,24 +491,31 @@ return result; } -void _glfwGetVideoModeX11(_GLFWmonitor* monitor, GLFWvidmode* mode)+GLFWbool _glfwGetVideoModeX11(_GLFWmonitor* monitor, GLFWvidmode* mode) { if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) { XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);- XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);+ const XRRModeInfo* mi = NULL; + XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); if (ci) {- const XRRModeInfo* mi = getModeInfo(sr, ci->mode);- if (mi) // mi can be NULL if the monitor has been disconnected+ mi = getModeInfo(sr, ci->mode);+ if (mi) *mode = vidmodeFromModeInfo(mi, ci); XRRFreeCrtcInfo(ci); } XRRFreeScreenResources(sr);++ if (!mi)+ {+ _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to query video mode");+ return GLFW_FALSE;+ } } else {@@ -519,6 +526,8 @@ _glfwSplitBPP(DefaultDepth(_glfw.x11.display, _glfw.x11.screen), &mode->redBits, &mode->greenBits, &mode->blueBits); }++ return GLFW_TRUE; } GLFWbool _glfwGetGammaRampX11(_GLFWmonitor* monitor, GLFWgammaramp* ramp)@@ -604,6 +613,13 @@ { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(None);++ if (_glfw.platform.platformID != GLFW_PLATFORM_X11)+ {+ _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "X11: Platform not initialized");+ return None;+ }+ return monitor->x11.crtc; } @@ -611,6 +627,15 @@ { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(None);++ if (_glfw.platform.platformID != GLFW_PLATFORM_X11)+ {+ _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "X11: Platform not initialized");+ return None;+ }+ return monitor->x11.output; }++#endif // _GLFW_X11
raylib/src/external/glfw/src/x11_platform.h view
@@ -968,7 +968,7 @@ void _glfwGetMonitorContentScaleX11(_GLFWmonitor* monitor, float* xscale, float* yscale); void _glfwGetMonitorWorkareaX11(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height); GLFWvidmode* _glfwGetVideoModesX11(_GLFWmonitor* monitor, int* count);-void _glfwGetVideoModeX11(_GLFWmonitor* monitor, GLFWvidmode* mode);+GLFWbool _glfwGetVideoModeX11(_GLFWmonitor* monitor, GLFWvidmode* mode); GLFWbool _glfwGetGammaRampX11(_GLFWmonitor* monitor, GLFWgammaramp* ramp); void _glfwSetGammaRampX11(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
raylib/src/external/glfw/src/x11_window.c view
@@ -1,8 +1,9 @@ //========================================================================-// GLFW 3.4 X11 - www.glfw.org+// GLFW 3.4 X11 (modified for raylib) - www.glfw.org; www.raylib.com //------------------------------------------------------------------------ // Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>+// Copyright (c) 2024 M374LX <wilsalx@gmail.com> // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages@@ -24,11 +25,11 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" +#if defined(_GLFW_X11)+ #include <X11/cursorfont.h> #include <X11/Xmd.h> @@ -79,24 +80,25 @@ // static GLFWbool waitForAnyEvent(double* timeout) {- nfds_t count = 2;- struct pollfd fds[3] =+ enum { XLIB_FD, PIPE_FD, INOTIFY_FD };+ struct pollfd fds[] = {- { ConnectionNumber(_glfw.x11.display), POLLIN },- { _glfw.x11.emptyEventPipe[0], POLLIN }+ [XLIB_FD] = { ConnectionNumber(_glfw.x11.display), POLLIN },+ [PIPE_FD] = { _glfw.x11.emptyEventPipe[0], POLLIN },+ [INOTIFY_FD] = { -1, POLLIN } }; -#if defined(__linux__)+#if defined(GLFW_BUILD_LINUX_JOYSTICK) if (_glfw.joysticksInitialized)- fds[count++] = (struct pollfd) { _glfw.linjs.inotify, POLLIN };+ fds[INOTIFY_FD].fd = _glfw.linjs.inotify; #endif while (!XPending(_glfw.x11.display)) {- if (!_glfwPollPOSIX(fds, count, timeout))+ if (!_glfwPollPOSIX(fds, sizeof(fds) / sizeof(fds[0]), timeout)) return GLFW_FALSE; - for (int i = 1; i < count; i++)+ for (int i = 1; i < sizeof(fds) / sizeof(fds[0]); i++) { if (fds[i].revents & POLLIN) return GLFW_TRUE;@@ -234,9 +236,9 @@ // Translates an X11 key code to a GLFW key token //-static int translateKey(int scancode)+static int translateKeyX11(int scancode) {- // Use the pre-filled LUT (see createKeyTables() in x11_init.c)+ // Use the pre-filled LUT (see createKeyTablesX11() in x11_init.c) if (scancode < 0 || scancode > 255) return GLFW_KEY_UNKNOWN; @@ -1080,7 +1082,7 @@ // Make the specified window and its video mode active on its monitor //-static void acquireMonitor(_GLFWwindow* window)+static void acquireMonitorX11(_GLFWwindow* window) { if (_glfw.x11.saver.count == 0) {@@ -1119,7 +1121,7 @@ // Remove the window and restore the original video mode //-static void releaseMonitor(_GLFWwindow* window)+static void releaseMonitorX11(_GLFWwindow* window) { if (window->monitor->window != window) return;@@ -1241,7 +1243,7 @@ case KeyPress: {- const int key = translateKey(keycode);+ const int key = translateKeyX11(keycode); const int mods = translateState(event->xkey.state); const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); @@ -1313,7 +1315,7 @@ case KeyRelease: {- const int key = translateKey(keycode);+ const int key = translateKeyX11(keycode); const int mods = translateState(event->xkey.state); if (!_glfw.x11.xkb.detectable)@@ -1487,6 +1489,9 @@ if (event->xconfigure.width != window->x11.width || event->xconfigure.height != window->x11.height) {+ window->x11.width = event->xconfigure.width;+ window->x11.height = event->xconfigure.height;+ _glfwInputFramebufferSize(window, event->xconfigure.width, event->xconfigure.height);@@ -1494,9 +1499,6 @@ _glfwInputWindowSize(window, event->xconfigure.width, event->xconfigure.height);-- window->x11.width = event->xconfigure.width;- window->x11.height = event->xconfigure.height; } int xpos = event->xconfigure.x;@@ -1524,9 +1526,10 @@ if (xpos != window->x11.xpos || ypos != window->x11.ypos) {- _glfwInputWindowPos(window, xpos, ypos); window->x11.xpos = xpos; window->x11.ypos = ypos;++ _glfwInputWindowPos(window, xpos, ypos); } return;@@ -1804,9 +1807,9 @@ if (window->monitor) { if (iconified)- releaseMonitor(window);+ releaseMonitorX11(window); else- acquireMonitor(window);+ acquireMonitorX11(window); } window->x11.iconified = iconified;@@ -2023,7 +2026,7 @@ { _glfwShowWindowX11(window); updateWindowMode(window);- acquireMonitor(window);+ acquireMonitorX11(window); if (wndconfig->centerCursor) _glfwCenterCursorInContentArea(window);@@ -2048,7 +2051,7 @@ enableCursor(window); if (window->monitor)- releaseMonitor(window);+ releaseMonitorX11(window); if (window->x11.ic) {@@ -2204,7 +2207,7 @@ if (window->monitor) { if (window->monitor->window == window)- acquireMonitor(window);+ acquireMonitorX11(window); } else {@@ -2475,7 +2478,7 @@ if (monitor) { if (monitor->window == window)- acquireMonitor(window);+ acquireMonitorX11(window); } else {@@ -2494,7 +2497,7 @@ { _glfwSetWindowDecoratedX11(window, window->decorated); _glfwSetWindowFloatingX11(window, window->floating);- releaseMonitor(window);+ releaseMonitorX11(window); } _glfwInputWindowMonitor(window, monitor);@@ -2509,7 +2512,7 @@ } updateWindowMode(window);- acquireMonitor(window);+ acquireMonitorX11(window); } else {@@ -2781,7 +2784,7 @@ { drainEmptyEvents(); -#if defined(__linux__)+#if defined(GLFW_BUILD_LINUX_JOYSTICK) if (_glfw.joysticksInitialized) _glfwDetectJoystickConnectionLinux(); #endif@@ -2901,14 +2904,16 @@ if (!_glfw.x11.xkb.available) return NULL; - if (scancode < 0 || scancode > 0xff ||- _glfw.x11.keycodes[scancode] == GLFW_KEY_UNKNOWN)+ if (scancode < 0 || scancode > 0xff) { _glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode); return NULL; } const int key = _glfw.x11.keycodes[scancode];+ if (key == GLFW_KEY_UNKNOWN)+ return NULL;+ const KeySym keysym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, _glfw.x11.xkb.group, 0); if (keysym == NoSymbol)@@ -3348,4 +3353,6 @@ return getSelectionString(_glfw.x11.PRIMARY); }++#endif // _GLFW_X11
raylib/src/external/glfw/src/xkb_unicode.c view
@@ -24,11 +24,10 @@ // distribution. // //========================================================================-// It is fine to use C99 in this file because it will not be built with VS-//======================================================================== #include "internal.h" +#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND) /* * Marcus: This code was originally written by Markus G. Kuhn.@@ -939,4 +938,6 @@ // No matching Unicode value found return GLFW_INVALID_CODEPOINT; }++#endif // _GLFW_WAYLAND or _GLFW_X11
raylib/src/external/vox_loader.h view
@@ -123,6 +123,7 @@ // Arrays for mesh build ArrayVector3 vertices;+ ArrayVector3 normals; ArrayUShort indices; ArrayColor colors; @@ -292,6 +293,16 @@ {1, 1, 1} //7 }; +const VoxVector3 FacesPerSideNormal[] = {+ { -1, 0, 0 }, //-X+ {1, 0, 0 }, //+X+ {0,-1, 0}, //-Y+ {0, 1, 0}, //+Y+ {0, 0, -1}, //-Z+ {0, 0, 1}, //+Z+};++ // Allocated VoxArray3D size static void Vox_AllocArray(VoxArray3D* pvoxarray, int _sx, int _sy, int _sz) {@@ -508,6 +519,11 @@ insertArrayVector3(&pvoxArray->vertices, vertComputed[v2]); insertArrayVector3(&pvoxArray->vertices, vertComputed[v3]); + insertArrayVector3(&pvoxArray->normals, FacesPerSideNormal[i]);+ insertArrayVector3(&pvoxArray->normals, FacesPerSideNormal[i]);+ insertArrayVector3(&pvoxArray->normals, FacesPerSideNormal[i]);+ insertArrayVector3(&pvoxArray->normals, FacesPerSideNormal[i]);+ VoxColor col = pvoxArray->palette[matID]; insertArrayColor(&pvoxArray->colors, col);@@ -653,6 +669,7 @@ // Init Arrays initArrayVector3(&pvoxarray->vertices, 3 * 1024);+ initArrayVector3(&pvoxarray->normals, 3 * 1024); initArrayUShort(&pvoxarray->indices, 3 * 1024); initArrayColor(&pvoxarray->colors, 3 * 1024);
raylib/src/platforms/rcore_android.c view
@@ -613,6 +613,12 @@ return 0; } +// Set gamepad vibration+void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)+{+ TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform");+}+ // Set mouse position XY void SetMousePosition(int x, int y) {
raylib/src/platforms/rcore_desktop.c view
@@ -74,7 +74,6 @@ //#define GLFW_EXPOSE_NATIVE_X11 // WARNING: Exposing Xlib.h > X.h results in dup symbols for Font type //#define GLFW_EXPOSE_NATIVE_WAYLAND- //#define GLFW_EXPOSE_NATIVE_MIR #include "GLFW/glfw3native.h" // Required for: glfwGetX11Window() #endif #if defined(__APPLE__)@@ -86,15 +85,6 @@ #endif //-----------------------------------------------------------------------------------// Defines and Macros-//-----------------------------------------------------------------------------------// TODO: HACK: Added flag if not provided by GLFW when using external library-// Latest GLFW release (GLFW 3.3.8) does not implement this flag, it was added for 3.4.0-dev-#if !defined(GLFW_MOUSE_PASSTHROUGH)- #define GLFW_MOUSE_PASSTHROUGH 0x0002000D-#endif--//---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- typedef struct {@@ -982,6 +972,8 @@ // Set cursor position in the middle SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); + if (glfwRawMouseMotionSupported()) glfwSetInputMode(platform.handle, GLFW_RAW_MOUSE_MOTION, GLFW_FALSE);+ CORE.Input.Mouse.cursorHidden = false; } @@ -993,6 +985,8 @@ // Set cursor position in the middle SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); + if (glfwRawMouseMotionSupported()) glfwSetInputMode(platform.handle, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);+ CORE.Input.Mouse.cursorHidden = true; } @@ -1050,6 +1044,12 @@ return glfwUpdateGamepadMappings(mappings); } +// Set gamepad vibration+void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)+{+ TRACELOG(LOG_WARNING, "GamepadSetVibration() not available on target platform");+}+ // Set mouse position XY void SetMousePosition(int x, int y) {@@ -1515,7 +1515,15 @@ // If graphic device is no properly initialized, we end program if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; }- else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2);+ else + {+ // Try to center window on screen but avoiding window-bar outside of screen+ int posX = GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2;+ int posY = GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2;+ if (posX < 0) posX = 0;+ if (posY < 0) posY = 0;+ SetWindowPosition(posX, posY);+ } // Load OpenGL extensions // NOTE: GL procedures address loader is required to load extensions@@ -1564,6 +1572,17 @@ CORE.Storage.basePath = GetWorkingDirectory(); //---------------------------------------------------------------------------- + char* glfwPlatform = "";+ switch (glfwGetPlatform())+ {+ case GLFW_PLATFORM_WIN32: glfwPlatform = "Win32"; break;+ case GLFW_PLATFORM_COCOA: glfwPlatform = "Cocoa"; break;+ case GLFW_PLATFORM_WAYLAND: glfwPlatform = "Wayland"; break;+ case GLFW_PLATFORM_X11: glfwPlatform = "X11"; break;+ case GLFW_PLATFORM_NULL: glfwPlatform = "Null"; break;+ }++ TRACELOG(LOG_INFO, "GLFW platform: %s", glfwPlatform); TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (GLFW): Initialized successfully"); return 0;@@ -1728,7 +1747,7 @@ // but future releases may add more actions (i.e. GLFW_REPEAT) CORE.Input.Mouse.currentButtonState[button] = action; CORE.Input.Touch.currentTouchState[button] = action;- + #if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES) // Process mouse events as touches to be able to use mouse-gestures GestureEvent gestureEvent = { 0 };
raylib/src/platforms/rcore_desktop_sdl.c view
@@ -938,6 +938,21 @@ return SDL_GameControllerAddMapping(mappings); } +// Set gamepad vibration+void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)+{+ //Limit input values to between 0.0f and 1.0f+ leftMotor = (0.0f > leftMotor) ? 0.0f : leftMotor;+ rightMotor = (0.0f > rightMotor) ? 0.0f : rightMotor;+ leftMotor = (1.0f < leftMotor) ? 1.0f : leftMotor;+ rightMotor = (1.0f < rightMotor) ? 1.0f : rightMotor;++ if (IsGamepadAvailable(gamepad))+ {+ SDL_JoystickRumble(platform.gamepad[gamepad], (Uint16)(leftMotor*65535.0f), (Uint16)(rightMotor*65535.0f), (Uint32)(MAX_GAMEPAD_VIBRATION_TIME*1000.0f));+ }+}+ // Set mouse position XY void SetMousePosition(int x, int y) {@@ -956,6 +971,22 @@ CORE.Input.Mouse.cursor = cursor; } +static void UpdateTouchPointsSDL(SDL_TouchFingerEvent event)+{+ CORE.Input.Touch.pointCount = SDL_GetNumTouchFingers(event.touchId);++ for (int i = 0; i < CORE.Input.Touch.pointCount; i++)+ {+ SDL_Finger *finger = SDL_GetTouchFinger(event.touchId, i);+ CORE.Input.Touch.pointId[i] = finger->id;+ CORE.Input.Touch.position[i].x = finger->x*CORE.Window.screen.width;+ CORE.Input.Touch.position[i].y = finger->y*CORE.Window.screen.height;+ CORE.Input.Touch.currentTouchState[i] = 1;+ }++ for (int i = CORE.Input.Touch.pointCount; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.currentTouchState[i] = 0;+}+ // Register all input events void PollInputEvents(void) {@@ -994,15 +1025,7 @@ // Register previous touch states for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i]; - // Reset touch positions- // TODO: It resets on target platform the mouse position and not filled again until a move-event,- // so, if mouse is not moved it returns a (0, 0) position... this behaviour should be reviewed!- //for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ 0, 0 };- // Map touch position to mouse position for convenience- // WARNING: If the target desktop device supports touch screen, this behavious should be reviewed!- // https://www.codeproject.com/Articles/668404/Programming-for-Multi-Touch- // https://docs.microsoft.com/en-us/windows/win32/wintouch/getting-started-with-multi-touch-messages CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE@@ -1085,11 +1108,17 @@ CORE.Window.currentFbo.height = height; CORE.Window.resizedLastFrame = true; } break;+ case SDL_WINDOWEVENT_ENTER:+ {+ CORE.Input.Mouse.cursorOnScreen = true;+ } break; case SDL_WINDOWEVENT_LEAVE:+ {+ CORE.Input.Mouse.cursorOnScreen = false;+ } break; case SDL_WINDOWEVENT_HIDDEN: case SDL_WINDOWEVENT_MINIMIZED: case SDL_WINDOWEVENT_FOCUS_LOST:- case SDL_WINDOWEVENT_ENTER: case SDL_WINDOWEVENT_SHOWN: case SDL_WINDOWEVENT_FOCUS_GAINED: case SDL_WINDOWEVENT_MAXIMIZED:@@ -1192,34 +1221,21 @@ touchAction = 2; } break; - // Check touch events- // NOTE: These cases need to be reviewed on a real touch screen case SDL_FINGERDOWN: {- const int touchId = (int)event.tfinger.fingerId;- CORE.Input.Touch.currentTouchState[touchId] = 1;- CORE.Input.Touch.position[touchId].x = event.tfinger.x * CORE.Window.screen.width;- CORE.Input.Touch.position[touchId].y = event.tfinger.y * CORE.Window.screen.height;-+ UpdateTouchPointsSDL(event.tfinger); touchAction = 1; realTouch = true; } break; case SDL_FINGERUP: {- const int touchId = (int)event.tfinger.fingerId;- CORE.Input.Touch.currentTouchState[touchId] = 0;- CORE.Input.Touch.position[touchId].x = event.tfinger.x * CORE.Window.screen.width;- CORE.Input.Touch.position[touchId].y = event.tfinger.y * CORE.Window.screen.height;-+ UpdateTouchPointsSDL(event.tfinger); touchAction = 0; realTouch = true; } break; case SDL_FINGERMOTION: {- const int touchId = (int)event.tfinger.fingerId;- CORE.Input.Touch.position[touchId].x = event.tfinger.x * CORE.Window.screen.width;- CORE.Input.Touch.position[touchId].y = event.tfinger.y * CORE.Window.screen.height;-+ UpdateTouchPointsSDL(event.tfinger); touchAction = 2; realTouch = true; } break;@@ -1228,7 +1244,9 @@ case SDL_JOYDEVICEADDED: { int jid = event.jdevice.which;- if (!CORE.Input.Gamepad.ready[jid] && (jid < MAX_GAMEPADS)) {++ if (!CORE.Input.Gamepad.ready[jid] && (jid < MAX_GAMEPADS))+ { platform.gamepad[jid] = SDL_JoystickOpen(jid); if (platform.gamepad[jid])@@ -1249,7 +1267,9 @@ case SDL_JOYDEVICEREMOVED: { int jid = event.jdevice.which;- if (jid == SDL_JoystickInstanceID(platform.gamepad[jid])) {++ if (jid == SDL_JoystickInstanceID(platform.gamepad[jid]))+ { SDL_JoystickClose(platform.gamepad[jid]); platform.gamepad[jid] = SDL_JoystickOpen(0); CORE.Input.Gamepad.ready[jid] = false;
raylib/src/platforms/rcore_drm.c view
@@ -59,1940 +59,1733 @@ #include <linux/input.h> // Linux: Keycodes constants definition (KEY_A, ...) #include <linux/joystick.h> // Linux: Joystick support library -#include <gbm.h> // Generic Buffer Management (native platform for EGL on DRM)-#include <xf86drm.h> // Direct Rendering Manager user-level library interface-#include <xf86drmMode.h> // Direct Rendering Manager mode setting (KMS) interface--#include "EGL/egl.h" // Native platform windowing system interface-#include "EGL/eglext.h" // EGL extensions--//-----------------------------------------------------------------------------------// Defines and Macros-//-----------------------------------------------------------------------------------#define USE_LAST_TOUCH_DEVICE // When multiple touchscreens are connected, only use the one with the highest event<N> number--#define DEFAULT_GAMEPAD_DEV "/dev/input/js" // Gamepad input (base dev for all gamepads: js0, js1, ...)-#define DEFAULT_EVDEV_PATH "/dev/input/" // Path to the linux input events--//-----------------------------------------------------------------------------------// Types and Structures Definition-//------------------------------------------------------------------------------------typedef struct {- pthread_t threadId; // Event reading thread id-- int fd; // File descriptor to the device it is assigned to- int eventNum; // Number of 'event<N>' device- Rectangle absRange; // Range of values for absolute pointing devices (touchscreens)- int touchSlot; // Hold the touch slot number of the currently being sent multitouch block- bool isMouse; // True if device supports relative X Y movements- bool isTouch; // True if device supports absolute X Y movements and has BTN_TOUCH- bool isMultitouch; // True if device supports multiple absolute movevents and has BTN_TOUCH- bool isKeyboard; // True if device has letter keycodes- bool isGamepad; // True if device has gamepad buttons-} InputEventWorker;--typedef struct {- // Display data- int fd; // File descriptor for /dev/dri/...- drmModeConnector *connector; // Direct Rendering Manager (DRM) mode connector- drmModeCrtc *crtc; // CRT Controller- int modeIndex; // Index of the used mode of connector->modes- struct gbm_device *gbmDevice; // GBM device- struct gbm_surface *gbmSurface; // GBM surface- struct gbm_bo *prevBO; // Previous GBM buffer object (during frame swapping)- uint32_t prevFB; // Previous GBM framebufer (during frame swapping)-- EGLDisplay device; // Native display device (physical screen connection)- EGLSurface surface; // Surface to draw on, framebuffers (connected to context)- EGLContext context; // Graphic context, mode in which drawing can be done- EGLConfig config; // Graphic config-- // Input data- InputEventWorker eventWorker[10]; // List of worker threads for every monitored "/dev/input/event<N>"-- // Keyboard data- int defaultKeyboardMode; // Default keyboard mode- bool eventKeyboardMode; // Keyboard in event mode- int defaultFileFlags; // Default IO file flags- struct termios defaultSettings; // Default keyboard settings- int keyboardFd; // File descriptor for the evdev keyboard-- // Mouse data- Vector2 eventWheelMove; // Registers the event mouse wheel variation- // NOTE: currentButtonState[] can't be written directly due to multithreading, app could miss the update- char currentButtonStateEvdev[MAX_MOUSE_BUTTONS]; // Holds the new mouse state for the next polling event to grab- bool cursorRelative; // Relative cursor mode- int mouseFd; // File descriptor for the evdev mouse/touch/gestures- Rectangle absRange; // Range of values for absolute pointing devices (touchscreens)- int touchSlot; // Hold the touch slot number of the currently being sent multitouch block-- // Gamepad data- int gamepadStreamFd[MAX_GAMEPADS]; // Gamepad device file descriptor--} PlatformData;--//-----------------------------------------------------------------------------------// Global Variables Definition-//-----------------------------------------------------------------------------------extern CoreData CORE; // Global CORE state context--static PlatformData platform = { 0 }; // Platform specific data--//-----------------------------------------------------------------------------------// Local Variables Definition-//-----------------------------------------------------------------------------------// Scancode to keycode mapping for US keyboards-// TODO: Replace this with a keymap from the X11 to get the correct regional map for the keyboard:-// Currently non US keyboards will have the wrong mapping for some keys-static const int keymapUS[] = {- 0, 256, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 259, 258, 81, 87, 69, 82, 84,- 89, 85, 73, 79, 80, 91, 93, 257, 341, 65, 83, 68, 70, 71, 72, 74, 75, 76, 59, 39, 96,- 340, 92, 90, 88, 67, 86, 66, 78, 77, 44, 46, 47, 344, 332, 342, 32, 280, 290, 291,- 292, 293, 294, 295, 296, 297, 298, 299, 282, 281, 327, 328, 329, 333, 324, 325,- 326, 334, 321, 322, 323, 320, 330, 0, 85, 86, 300, 301, 89, 90, 91, 92, 93, 94, 95,- 335, 345, 331, 283, 346, 101, 268, 265, 266, 263, 262, 269, 264, 267, 260, 261,- 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 347, 127,- 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,- 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,- 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,- 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,- 192, 193, 194, 0, 0, 0, 0, 0, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210,- 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226,- 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,- 243, 244, 245, 246, 247, 248, 0, 0, 0, 0, 0, 0, 0-};--// NOTE: The complete evdev EV_KEY list can be found at /usr/include/linux/input-event-codes.h-// TODO: Complete the LUT with all unicode decimal values-static const int EvkeyToUnicodeLUT[] = {- 0, 27, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 8, 0, 113, 119, 101, 114,- 116, 121, 117, 105, 111, 112, 0, 0, 13, 0, 97, 115, 100, 102, 103, 104, 106, 107, 108, 59,- 39, 96, 0, 92, 122, 120, 99, 118, 98, 110, 109, 44, 46, 47, 0, 0, 0, 32- // LUT currently incomplete, just mapped the most essential keys-};--//-----------------------------------------------------------------------------------// Module Internal Functions Declaration-//-----------------------------------------------------------------------------------int InitPlatform(void); // Initialize platform (graphics, inputs and more)-void ClosePlatform(void); // Close platform--static void InitKeyboard(void); // Initialize raw keyboard system-static void RestoreKeyboard(void); // Restore keyboard system-#if defined(SUPPORT_SSH_KEYBOARD_RPI)-static void ProcessKeyboard(void); // Process keyboard events-#endif--static void InitEvdevInput(void); // Initialize evdev inputs-static void ConfigureEvdevDevice(char *device); // Identifies a input device and configures it for use if appropriate-static void PollKeyboardEvents(void); // Process evdev keyboard events-static void *EventThread(void *arg); // Input device events reading thread--static void InitGamepad(void); // Initialize raw gamepad input-static void PollGamepadEvents(void); // Gamepad reading function--static int FindMatchingConnectorMode(const drmModeConnector *connector, const drmModeModeInfo *mode); // Search matching DRM mode in connector's mode list-static int FindExactConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search exactly matching DRM connector mode in connector's list-static int FindNearestConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search the nearest matching DRM connector mode in connector's list--//-----------------------------------------------------------------------------------// Module Functions Declaration-//-----------------------------------------------------------------------------------// NOTE: Functions declaration is provided by raylib.h--//-----------------------------------------------------------------------------------// Module Functions Definition: Window and Graphics Device-//------------------------------------------------------------------------------------// Check if application should close-// NOTE: By default, if KEY_ESCAPE pressed-bool WindowShouldClose(void)-{- if (CORE.Window.ready) return CORE.Window.shouldClose;- else return true;-}--// Toggle fullscreen mode-void ToggleFullscreen(void)-{- TRACELOG(LOG_WARNING, "ToggleFullscreen() not available on target platform");-}--// Toggle borderless windowed mode-void ToggleBorderlessWindowed(void)-{- TRACELOG(LOG_WARNING, "ToggleBorderlessWindowed() not available on target platform");-}--// Set window state: maximized, if resizable-void MaximizeWindow(void)-{- TRACELOG(LOG_WARNING, "MaximizeWindow() not available on target platform");-}--// Set window state: minimized-void MinimizeWindow(void)-{- TRACELOG(LOG_WARNING, "MinimizeWindow() not available on target platform");-}--// Set window state: not minimized/maximized-void RestoreWindow(void)-{- TRACELOG(LOG_WARNING, "RestoreWindow() not available on target platform");-}--// Set window configuration state using flags-void SetWindowState(unsigned int flags)-{- TRACELOG(LOG_WARNING, "SetWindowState() not available on target platform");-}--// Clear window configuration state flags-void ClearWindowState(unsigned int flags)-{- TRACELOG(LOG_WARNING, "ClearWindowState() not available on target platform");-}--// Set icon for window-void SetWindowIcon(Image image)-{- TRACELOG(LOG_WARNING, "SetWindowIcon() not available on target platform");-}--// Set icon for window-void SetWindowIcons(Image *images, int count)-{- TRACELOG(LOG_WARNING, "SetWindowIcons() not available on target platform");-}--// Set title for window-void SetWindowTitle(const char *title)-{- CORE.Window.title = title;-}--// Set window position on screen (windowed mode)-void SetWindowPosition(int x, int y)-{- TRACELOG(LOG_WARNING, "SetWindowPosition() not available on target platform");-}--// Set monitor for the current window-void SetWindowMonitor(int monitor)-{- TRACELOG(LOG_WARNING, "SetWindowMonitor() not available on target platform");-}--// Set window minimum dimensions (FLAG_WINDOW_RESIZABLE)-void SetWindowMinSize(int width, int height)-{- CORE.Window.screenMin.width = width;- CORE.Window.screenMin.height = height;-}--// Set window maximum dimensions (FLAG_WINDOW_RESIZABLE)-void SetWindowMaxSize(int width, int height)-{- CORE.Window.screenMax.width = width;- CORE.Window.screenMax.height = height;-}--// Set window dimensions-void SetWindowSize(int width, int height)-{- TRACELOG(LOG_WARNING, "SetWindowSize() not available on target platform");-}--// Set window opacity, value opacity is between 0.0 and 1.0-void SetWindowOpacity(float opacity)-{- TRACELOG(LOG_WARNING, "SetWindowOpacity() not available on target platform");-}--// Set window focused-void SetWindowFocused(void)-{- TRACELOG(LOG_WARNING, "SetWindowFocused() not available on target platform");-}--// Get native window handle-void *GetWindowHandle(void)-{- TRACELOG(LOG_WARNING, "GetWindowHandle() not implemented on target platform");- return NULL;-}--// Get number of monitors-int GetMonitorCount(void)-{- TRACELOG(LOG_WARNING, "GetMonitorCount() not implemented on target platform");- return 1;-}--// Get number of monitors-int GetCurrentMonitor(void)-{- TRACELOG(LOG_WARNING, "GetCurrentMonitor() not implemented on target platform");- return 0;-}--// Get selected monitor position-Vector2 GetMonitorPosition(int monitor)-{- TRACELOG(LOG_WARNING, "GetMonitorPosition() not implemented on target platform");- return (Vector2){ 0, 0 };-}--// Get selected monitor width (currently used by monitor)-int GetMonitorWidth(int monitor)-{- TRACELOG(LOG_WARNING, "GetMonitorWidth() not implemented on target platform");- return 0;-}--// Get selected monitor height (currently used by monitor)-int GetMonitorHeight(int monitor)-{- TRACELOG(LOG_WARNING, "GetMonitorHeight() not implemented on target platform");- return 0;-}--// Get selected monitor physical width in millimetres-int GetMonitorPhysicalWidth(int monitor)-{- TRACELOG(LOG_WARNING, "GetMonitorPhysicalWidth() not implemented on target platform");- return 0;-}--// Get selected monitor physical height in millimetres-int GetMonitorPhysicalHeight(int monitor)-{- TRACELOG(LOG_WARNING, "GetMonitorPhysicalHeight() not implemented on target platform");- return 0;-}--// Get selected monitor refresh rate-int GetMonitorRefreshRate(int monitor)-{- int refresh = 0;-- if ((platform.connector) && (platform.modeIndex >= 0))- {- refresh = platform.connector->modes[platform.modeIndex].vrefresh;- }-- return refresh;-}--// Get the human-readable, UTF-8 encoded name of the selected monitor-const char *GetMonitorName(int monitor)-{- TRACELOG(LOG_WARNING, "GetMonitorName() not implemented on target platform");- return "";-}--// Get window position XY on monitor-Vector2 GetWindowPosition(void)-{- return (Vector2){ 0, 0 };-}--// Get window scale DPI factor for current monitor-Vector2 GetWindowScaleDPI(void)-{- return (Vector2){ 1.0f, 1.0f };-}--// Set clipboard text content-void SetClipboardText(const char *text)-{- TRACELOG(LOG_WARNING, "SetClipboardText() not implemented on target platform");-}--// Get clipboard text content-// NOTE: returned string is allocated and freed by GLFW-const char *GetClipboardText(void)-{- TRACELOG(LOG_WARNING, "GetClipboardText() not implemented on target platform");- return NULL;-}--// Show mouse cursor-void ShowCursor(void)-{- CORE.Input.Mouse.cursorHidden = false;-}--// Hides mouse cursor-void HideCursor(void)-{- CORE.Input.Mouse.cursorHidden = true;-}--// Enables cursor (unlock cursor)-void EnableCursor(void)-{- // Set cursor position in the middle- SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);-- platform.cursorRelative = false;- CORE.Input.Mouse.cursorHidden = false;-}--// Disables cursor (lock cursor)-void DisableCursor(void)-{- // Set cursor position in the middle- SetMousePosition(0, 0);-- platform.cursorRelative = true;- CORE.Input.Mouse.cursorHidden = true;-}--// Swap back buffer with front buffer (screen drawing)-void SwapScreenBuffer(void)-{- eglSwapBuffers(platform.device, platform.surface);-- if (!platform.gbmSurface || (-1 == platform.fd) || !platform.connector || !platform.crtc) TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap");-- struct gbm_bo *bo = gbm_surface_lock_front_buffer(platform.gbmSurface);- if (!bo) TRACELOG(LOG_ERROR, "DISPLAY: Failed GBM to lock front buffer");-- uint32_t fb = 0;- int result = drmModeAddFB(platform.fd, platform.connector->modes[platform.modeIndex].hdisplay, platform.connector->modes[platform.modeIndex].vdisplay, 24, 32, gbm_bo_get_stride(bo), gbm_bo_get_handle(bo).u32, &fb);- if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeAddFB() failed with result: %d", result);-- result = drmModeSetCrtc(platform.fd, platform.crtc->crtc_id, fb, 0, 0, &platform.connector->connector_id, 1, &platform.connector->modes[platform.modeIndex]);- if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeSetCrtc() failed with result: %d", result);-- if (platform.prevFB)- {- result = drmModeRmFB(platform.fd, platform.prevFB);- if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeRmFB() failed with result: %d", result);- }-- platform.prevFB = fb;-- if (platform.prevBO) gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);-- platform.prevBO = bo;-}--//-----------------------------------------------------------------------------------// Module Functions Definition: Misc-//------------------------------------------------------------------------------------// Get elapsed time measure in seconds since InitTimer()-double GetTime(void)-{- double time = 0.0;- struct timespec ts = { 0 };- clock_gettime(CLOCK_MONOTONIC, &ts);- unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;-- time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()-- return time;-}--// Open URL with default system browser (if available)-// NOTE: This function is only safe to use if you control the URL given.-// A user could craft a malicious string performing another action.-// Only call this function yourself not with user input or make sure to check the string yourself.-// Ref: https://github.com/raysan5/raylib/issues/686-void OpenURL(const char *url)-{- TRACELOG(LOG_WARNING, "OpenURL() not implemented on target platform");-}--//-----------------------------------------------------------------------------------// Module Functions Definition: Inputs-//------------------------------------------------------------------------------------// Set internal gamepad mappings-int SetGamepadMappings(const char *mappings)-{- TRACELOG(LOG_WARNING, "SetGamepadMappings() not implemented on target platform");- return 0;-}--// Set mouse position XY-void SetMousePosition(int x, int y)-{- CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };- CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;-}--// Set mouse cursor-void SetMouseCursor(int cursor)-{- TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform");-}--// Register all input events-void PollInputEvents(void)-{-#if defined(SUPPORT_GESTURES_SYSTEM)- // NOTE: Gestures update must be called every frame to reset gestures correctly- // because ProcessGestureEvent() is just called on an event, not every frame- UpdateGestures();-#endif-- // Reset keys/chars pressed registered- CORE.Input.Keyboard.keyPressedQueueCount = 0;- CORE.Input.Keyboard.charPressedQueueCount = 0;-- // Reset last gamepad button/axis registered state- CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN- //CORE.Input.Gamepad.axisCount = 0;-- // Register previous keys states- for (int i = 0; i < MAX_KEYBOARD_KEYS; i++)- {- CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];- CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;- }-- PollKeyboardEvents();-- // Register previous mouse position- if (platform.cursorRelative) CORE.Input.Mouse.currentPosition = (Vector2){ 0.0f, 0.0f };- else CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;-- // Register previous mouse states- CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove;- CORE.Input.Mouse.currentWheelMove = platform.eventWheelMove;- platform.eventWheelMove = (Vector2){ 0.0f, 0.0f };- for (int i = 0; i < MAX_MOUSE_BUTTONS; i++)- {- CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];- CORE.Input.Mouse.currentButtonState[i] = platform.currentButtonStateEvdev[i];- CORE.Input.Touch.currentTouchState[i] = platform.currentButtonStateEvdev[i];- }-- // Register gamepads buttons events- PollGamepadEvents();-- // Register previous touch states- for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i];-- // Reset touch positions- //for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ 0, 0 };-- // Map touch position to mouse position for convenience- CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;--#if defined(SUPPORT_SSH_KEYBOARD_RPI)- // NOTE: Keyboard reading could be done using input_event(s) or just read from stdin, both methods are used here.- // stdin reading is still used for legacy purposes, it allows keyboard input trough SSH console-- if (!platform.eventKeyboardMode) ProcessKeyboard();-#endif-- // Handle the mouse/touch/gestures events:- // NOTE: Replaces the EventThread handling that is now commented.- {- int fd = platform.mouseFd;- if (fd == -1) return;-- struct input_event event = { 0 };-- int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE-- // Try to read data from the mouse/touch/gesture and only continue if successful- while (read(fd, &event, sizeof(event)) == (int)sizeof(event))- {- // Relative movement parsing- if (event.type == EV_REL)- {- if (event.code == REL_X)- {- if (platform.cursorRelative)- {- CORE.Input.Mouse.currentPosition.x = event.value;- CORE.Input.Mouse.previousPosition.x = 0.0f;- }- else CORE.Input.Mouse.currentPosition.x += event.value;- CORE.Input.Touch.position[0].x = CORE.Input.Mouse.currentPosition.x;-- touchAction = 2; // TOUCH_ACTION_MOVE- }-- if (event.code == REL_Y)- {- if (platform.cursorRelative)- {- CORE.Input.Mouse.currentPosition.y = event.value;- CORE.Input.Mouse.previousPosition.y = 0.0f;- }- else CORE.Input.Mouse.currentPosition.y += event.value;- CORE.Input.Touch.position[0].y = CORE.Input.Mouse.currentPosition.y;-- touchAction = 2; // TOUCH_ACTION_MOVE- }-- if (event.code == REL_WHEEL) platform.eventWheelMove.y += event.value;- }-- // Absolute movement parsing- if (event.type == EV_ABS)- {- // Basic movement- if (event.code == ABS_X)- {- CORE.Input.Mouse.currentPosition.x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange- CORE.Input.Touch.position[0].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange-- touchAction = 2; // TOUCH_ACTION_MOVE- }-- if (event.code == ABS_Y)- {- CORE.Input.Mouse.currentPosition.y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange- CORE.Input.Touch.position[0].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange-- touchAction = 2; // TOUCH_ACTION_MOVE- }-- // Multitouch movement- if (event.code == ABS_MT_SLOT) platform.touchSlot = event.value; // Remember the slot number for the folowing events-- if (event.code == ABS_MT_POSITION_X)- {- if (platform.touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[platform.touchSlot].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange- }-- if (event.code == ABS_MT_POSITION_Y)- {- if (platform.touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[platform.touchSlot].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange- }-- if (event.code == ABS_MT_TRACKING_ID)- {- if ((event.value < 0) && (platform.touchSlot < MAX_TOUCH_POINTS))- {- // Touch has ended for this point- CORE.Input.Touch.position[platform.touchSlot].x = -1;- CORE.Input.Touch.position[platform.touchSlot].y = -1;- }- }-- // Touchscreen tap- if (event.code == ABS_PRESSURE)- {- int previousMouseLeftButtonState = platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT];-- if (!event.value && previousMouseLeftButtonState)- {- platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0;-- touchAction = 0; // TOUCH_ACTION_UP- }-- if (event.value && !previousMouseLeftButtonState)- {- platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 1;-- touchAction = 1; // TOUCH_ACTION_DOWN- }- }-- }-- // Button parsing- if (event.type == EV_KEY)- {- // Mouse button parsing- if ((event.code == BTN_TOUCH) || (event.code == BTN_LEFT))- {- platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = event.value;-- if (event.value > 0) touchAction = 1; // TOUCH_ACTION_DOWN- else touchAction = 0; // TOUCH_ACTION_UP- }-- if (event.code == BTN_RIGHT) platform.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value;- if (event.code == BTN_MIDDLE) platform.currentButtonStateEvdev[MOUSE_BUTTON_MIDDLE] = event.value;- if (event.code == BTN_SIDE) platform.currentButtonStateEvdev[MOUSE_BUTTON_SIDE] = event.value;- if (event.code == BTN_EXTRA) platform.currentButtonStateEvdev[MOUSE_BUTTON_EXTRA] = event.value;- if (event.code == BTN_FORWARD) platform.currentButtonStateEvdev[MOUSE_BUTTON_FORWARD] = event.value;- if (event.code == BTN_BACK) platform.currentButtonStateEvdev[MOUSE_BUTTON_BACK] = event.value;- }-- // Screen confinement- if (!CORE.Input.Mouse.cursorHidden)- {- if (CORE.Input.Mouse.currentPosition.x < 0) CORE.Input.Mouse.currentPosition.x = 0;- if (CORE.Input.Mouse.currentPosition.x > CORE.Window.screen.width/CORE.Input.Mouse.scale.x) CORE.Input.Mouse.currentPosition.x = CORE.Window.screen.width/CORE.Input.Mouse.scale.x;-- if (CORE.Input.Mouse.currentPosition.y < 0) CORE.Input.Mouse.currentPosition.y = 0;- if (CORE.Input.Mouse.currentPosition.y > CORE.Window.screen.height/CORE.Input.Mouse.scale.y) CORE.Input.Mouse.currentPosition.y = CORE.Window.screen.height/CORE.Input.Mouse.scale.y;- }-- // Update touch point count- CORE.Input.Touch.pointCount = 0;- for (int i = 0; i < MAX_TOUCH_POINTS; i++)- {- if (CORE.Input.Touch.position[i].x >= 0) CORE.Input.Touch.pointCount++;- }--#if defined(SUPPORT_GESTURES_SYSTEM)- if (touchAction > -1)- {- GestureEvent gestureEvent = { 0 };-- gestureEvent.touchAction = touchAction;- gestureEvent.pointCount = CORE.Input.Touch.pointCount;-- for (int i = 0; i < MAX_TOUCH_POINTS; i++)- {- gestureEvent.pointId[i] = i;- gestureEvent.position[i] = CORE.Input.Touch.position[i];- }-- ProcessGestureEvent(gestureEvent);-- touchAction = -1;- }-#endif- }- }-}--//-----------------------------------------------------------------------------------// Module Internal Functions Definition-//------------------------------------------------------------------------------------// Initialize platform: graphics, inputs and more-int InitPlatform(void)-{- platform.fd = -1;- platform.connector = NULL;- platform.modeIndex = -1;- platform.crtc = NULL;- platform.gbmDevice = NULL;- platform.gbmSurface = NULL;- platform.prevBO = NULL;- platform.prevFB = 0;-- // Initialize graphic device: display/window and graphic context- //----------------------------------------------------------------------------- CORE.Window.fullscreen = true;- CORE.Window.flags |= FLAG_FULLSCREEN_MODE;--#if defined(DEFAULT_GRAPHIC_DEVICE_DRM)- platform.fd = open(DEFAULT_GRAPHIC_DEVICE_DRM, O_RDWR);-#else- TRACELOG(LOG_INFO, "DISPLAY: No graphic card set, trying platform-gpu-card");- platform.fd = open("/dev/dri/by-path/platform-gpu-card", O_RDWR); // VideoCore VI (Raspberry Pi 4)-- if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL))- {- TRACELOG(LOG_INFO, "DISPLAY: Failed to open platform-gpu-card, trying card1");- platform.fd = open("/dev/dri/card1", O_RDWR); // Other Embedded- }-- if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL))- {- TRACELOG(LOG_INFO, "DISPLAY: Failed to open graphic card1, trying card0");- platform.fd = open("/dev/dri/card0", O_RDWR); // VideoCore IV (Raspberry Pi 1-3)- }-#endif-- if (platform.fd == -1)- {- TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card");- return -1;- }-- drmModeRes *res = drmModeGetResources(platform.fd);- if (!res)- {- TRACELOG(LOG_WARNING, "DISPLAY: Failed get DRM resources");- return -1;- }-- TRACELOG(LOG_TRACE, "DISPLAY: Connectors found: %i", res->count_connectors);-- for (size_t i = 0; i < res->count_connectors; i++)- {- TRACELOG(LOG_TRACE, "DISPLAY: Connector index %i", i);-- drmModeConnector *con = drmModeGetConnector(platform.fd, res->connectors[i]);- TRACELOG(LOG_TRACE, "DISPLAY: Connector modes detected: %i", con->count_modes);-- if ((con->connection == DRM_MODE_CONNECTED) && (con->encoder_id))- {- TRACELOG(LOG_TRACE, "DISPLAY: DRM mode connected");- platform.connector = con;- break;- }- else- {- TRACELOG(LOG_TRACE, "DISPLAY: DRM mode NOT connected (deleting)");- drmModeFreeConnector(con);- }- }-- if (!platform.connector)- {- TRACELOG(LOG_WARNING, "DISPLAY: No suitable DRM connector found");- drmModeFreeResources(res);- return -1;- }-- drmModeEncoder *enc = drmModeGetEncoder(platform.fd, platform.connector->encoder_id);- if (!enc)- {- TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode encoder");- drmModeFreeResources(res);- return -1;- }-- platform.crtc = drmModeGetCrtc(platform.fd, enc->crtc_id);- if (!platform.crtc)- {- TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode crtc");- drmModeFreeEncoder(enc);- drmModeFreeResources(res);- return -1;- }-- // If InitWindow should use the current mode find it in the connector's mode list- if ((CORE.Window.screen.width <= 0) || (CORE.Window.screen.height <= 0))- {- TRACELOG(LOG_TRACE, "DISPLAY: Selecting DRM connector mode for current used mode...");-- platform.modeIndex = FindMatchingConnectorMode(platform.connector, &platform.crtc->mode);-- if (platform.modeIndex < 0)- {- TRACELOG(LOG_WARNING, "DISPLAY: No matching DRM connector mode found");- drmModeFreeEncoder(enc);- drmModeFreeResources(res);- return -1;- }-- CORE.Window.screen.width = CORE.Window.display.width;- CORE.Window.screen.height = CORE.Window.display.height;- }-- const bool allowInterlaced = CORE.Window.flags & FLAG_INTERLACED_HINT;- const int fps = (CORE.Time.target > 0)? (1.0/CORE.Time.target) : 60;-- // Try to find an exact matching mode- platform.modeIndex = FindExactConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);-- // If nothing found, try to find a nearly matching mode- if (platform.modeIndex < 0) platform.modeIndex = FindNearestConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);-- // If nothing found, try to find an exactly matching mode including interlaced- if (platform.modeIndex < 0) platform.modeIndex = FindExactConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true);-- // If nothing found, try to find a nearly matching mode including interlaced- if (platform.modeIndex < 0) platform.modeIndex = FindNearestConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true);-- // If nothing found, there is no suitable mode- if (platform.modeIndex < 0)- {- TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable DRM connector mode");- drmModeFreeEncoder(enc);- drmModeFreeResources(res);- return -1;- }-- CORE.Window.display.width = platform.connector->modes[platform.modeIndex].hdisplay;- CORE.Window.display.height = platform.connector->modes[platform.modeIndex].vdisplay;-- TRACELOG(LOG_INFO, "DISPLAY: Selected DRM connector mode %s (%ux%u%c@%u)", platform.connector->modes[platform.modeIndex].name,- platform.connector->modes[platform.modeIndex].hdisplay, platform.connector->modes[platform.modeIndex].vdisplay,- (platform.connector->modes[platform.modeIndex].flags & DRM_MODE_FLAG_INTERLACE)? 'i' : 'p',- platform.connector->modes[platform.modeIndex].vrefresh);-- // Use the width and height of the surface for render- CORE.Window.render.width = CORE.Window.screen.width;- CORE.Window.render.height = CORE.Window.screen.height;-- drmModeFreeEncoder(enc);- enc = NULL;-- drmModeFreeResources(res);- res = NULL;-- platform.gbmDevice = gbm_create_device(platform.fd);- if (!platform.gbmDevice)- {- TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM device");- return -1;- }-- platform.gbmSurface = gbm_surface_create(platform.gbmDevice, platform.connector->modes[platform.modeIndex].hdisplay,- platform.connector->modes[platform.modeIndex].vdisplay, GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);- if (!platform.gbmSurface)- {- TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM surface");- return -1;- }-- EGLint samples = 0;- EGLint sampleBuffer = 0;- if (CORE.Window.flags & FLAG_MSAA_4X_HINT)- {- samples = 4;- sampleBuffer = 1;- TRACELOG(LOG_INFO, "DISPLAY: Trying to enable MSAA x4");- }-- const EGLint framebufferAttribs[] =- {- EGL_RENDERABLE_TYPE, (rlGetVersion() == RL_OPENGL_ES_30)? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT, // Type of context support- EGL_SURFACE_TYPE, EGL_WINDOW_BIT, // Don't use it on Android!- EGL_RED_SIZE, 8, // RED color bit depth (alternative: 5)- EGL_GREEN_SIZE, 8, // GREEN color bit depth (alternative: 6)- EGL_BLUE_SIZE, 8, // BLUE color bit depth (alternative: 5)- EGL_ALPHA_SIZE, 8, // ALPHA bit depth (required for transparent framebuffer)- //EGL_TRANSPARENT_TYPE, EGL_NONE, // Request transparent framebuffer (EGL_TRANSPARENT_RGB does not work on RPI)- EGL_DEPTH_SIZE, 16, // Depth buffer size (Required to use Depth testing!)- //EGL_STENCIL_SIZE, 8, // Stencil buffer size- EGL_SAMPLE_BUFFERS, sampleBuffer, // Activate MSAA- EGL_SAMPLES, samples, // 4x Antialiasing if activated (Free on MALI GPUs)- EGL_NONE- };-- const EGLint contextAttribs[] = {- EGL_CONTEXT_CLIENT_VERSION, 2,- EGL_NONE- };-- EGLint numConfigs = 0;-- // Get an EGL device connection- platform.device = eglGetDisplay((EGLNativeDisplayType)platform.gbmDevice);- if (platform.device == EGL_NO_DISPLAY)- {- TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");- return -1;- }-- // Initialize the EGL device connection- if (eglInitialize(platform.device, NULL, NULL) == EGL_FALSE)- {- // If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.- TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");- return -1;- }-- if (!eglChooseConfig(platform.device, NULL, NULL, 0, &numConfigs))- {- TRACELOG(LOG_WARNING, "DISPLAY: Failed to get EGL config count: 0x%x", eglGetError());- return -1;- }-- TRACELOG(LOG_TRACE, "DISPLAY: EGL configs available: %d", numConfigs);-- EGLConfig *configs = RL_CALLOC(numConfigs, sizeof(*configs));- if (!configs)- {- TRACELOG(LOG_WARNING, "DISPLAY: Failed to get memory for EGL configs");- return -1;- }-- EGLint matchingNumConfigs = 0;- if (!eglChooseConfig(platform.device, framebufferAttribs, configs, numConfigs, &matchingNumConfigs))- {- TRACELOG(LOG_WARNING, "DISPLAY: Failed to choose EGL config: 0x%x", eglGetError());- free(configs);- return -1;- }-- TRACELOG(LOG_TRACE, "DISPLAY: EGL matching configs available: %d", matchingNumConfigs);-- // find the EGL config that matches the previously setup GBM format- int found = 0;- for (EGLint i = 0; i < matchingNumConfigs; ++i)- {- EGLint id = 0;- if (!eglGetConfigAttrib(platform.device, configs[i], EGL_NATIVE_VISUAL_ID, &id))- {- TRACELOG(LOG_WARNING, "DISPLAY: Failed to get EGL config attribute: 0x%x", eglGetError());- continue;- }-- if (GBM_FORMAT_ARGB8888 == id)- {- TRACELOG(LOG_TRACE, "DISPLAY: Using EGL config: %d", i);- platform.config = configs[i];- found = 1;- break;- }- }-- RL_FREE(configs);-- if (!found)- {- TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable EGL config");- return -1;- }-- // Set rendering API- eglBindAPI(EGL_OPENGL_ES_API);-- // Create an EGL rendering context- platform.context = eglCreateContext(platform.device, platform.config, EGL_NO_CONTEXT, contextAttribs);- if (platform.context == EGL_NO_CONTEXT)- {- TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");- return -1;- }-- // Create an EGL window surface- platform.surface = eglCreateWindowSurface(platform.device, platform.config, (EGLNativeWindowType)platform.gbmSurface, NULL);- if (EGL_NO_SURFACE == platform.surface)- {- TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL window surface: 0x%04x", eglGetError());- return -1;- }-- // At this point we need to manage render size vs screen size- // NOTE: This function use and modify global module variables:- // -> CORE.Window.screen.width/CORE.Window.screen.height- // -> CORE.Window.render.width/CORE.Window.render.height- // -> CORE.Window.screenScale- SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);-- // There must be at least one frame displayed before the buffers are swapped- //eglSwapInterval(platform.device, 1);-- EGLBoolean result = eglMakeCurrent(platform.device, platform.surface, platform.surface, platform.context);-- // Check surface and context activation- if (result != EGL_FALSE)- {- CORE.Window.ready = true;-- CORE.Window.render.width = CORE.Window.screen.width;- CORE.Window.render.height = CORE.Window.screen.height;- CORE.Window.currentFbo.width = CORE.Window.render.width;- CORE.Window.currentFbo.height = CORE.Window.render.height;-- TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully");- TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height);- TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height);- TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);- TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);- }- else- {- TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphics device");- return -1;- }-- if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();-- // If graphic device is no properly initialized, we end program- if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; }- else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor()) / 2 - CORE.Window.screen.width / 2, GetMonitorHeight(GetCurrentMonitor()) / 2 - CORE.Window.screen.height / 2);-- // Set some default window flags- CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false- CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false- CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true- CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false-- // Load OpenGL extensions- // NOTE: GL procedures address loader is required to load extensions- rlLoadExtensions(eglGetProcAddress);- //------------------------------------------------------------------------------ // Initialize timming system- //----------------------------------------------------------------------------- // NOTE: timming system must be initialized before the input events system- InitTimer();- //------------------------------------------------------------------------------ // Initialize input events system- //----------------------------------------------------------------------------- InitEvdevInput(); // Evdev inputs initialization- InitGamepad(); // Gamepad init- InitKeyboard(); // Keyboard init (stdin)- //------------------------------------------------------------------------------ // Initialize storage system- //----------------------------------------------------------------------------- CORE.Storage.basePath = GetWorkingDirectory();- //------------------------------------------------------------------------------ TRACELOG(LOG_INFO, "PLATFORM: DRM: Initialized successfully");-- return 0;-}--// Close platform-void ClosePlatform(void)-{- if (platform.prevFB)- {- drmModeRmFB(platform.fd, platform.prevFB);- platform.prevFB = 0;- }-- if (platform.prevBO)- {- gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);- platform.prevBO = NULL;- }-- if (platform.gbmSurface)- {- gbm_surface_destroy(platform.gbmSurface);- platform.gbmSurface = NULL;- }-- if (platform.gbmDevice)- {- gbm_device_destroy(platform.gbmDevice);- platform.gbmDevice = NULL;- }-- if (platform.crtc)- {- if (platform.connector)- {- drmModeSetCrtc(platform.fd, platform.crtc->crtc_id, platform.crtc->buffer_id,- platform.crtc->x, platform.crtc->y, &platform.connector->connector_id, 1, &platform.crtc->mode);- drmModeFreeConnector(platform.connector);- platform.connector = NULL;- }-- drmModeFreeCrtc(platform.crtc);- platform.crtc = NULL;- }-- if (platform.fd != -1)- {- close(platform.fd);- platform.fd = -1;- }-- // Close surface, context and display- if (platform.device != EGL_NO_DISPLAY)- {- if (platform.surface != EGL_NO_SURFACE)- {- eglDestroySurface(platform.device, platform.surface);- platform.surface = EGL_NO_SURFACE;- }-- if (platform.context != EGL_NO_CONTEXT)- {- eglDestroyContext(platform.device, platform.context);- platform.context = EGL_NO_CONTEXT;- }-- eglTerminate(platform.device);- platform.device = EGL_NO_DISPLAY;- }-- // Wait for mouse and gamepad threads to finish before closing- // NOTE: Those threads should already have finished at this point- // because they are controlled by CORE.Window.shouldClose variable-- CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called-- // Close the evdev keyboard- if (platform.keyboardFd != -1)- {- close(platform.keyboardFd);- platform.keyboardFd = -1;- }-- for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)- {- if (platform.eventWorker[i].threadId)- {- pthread_join(platform.eventWorker[i].threadId, NULL);- }- }-}--// Initialize Keyboard system (using standard input)-static void InitKeyboard(void)-{- // NOTE: We read directly from Standard Input (stdin) - STDIN_FILENO file descriptor,- // Reading directly from stdin will give chars already key-mapped by kernel to ASCII or UNICODE-- // Save terminal keyboard settings- tcgetattr(STDIN_FILENO, &platform.defaultSettings);-- // Reconfigure terminal with new settings- struct termios keyboardNewSettings = { 0 };- keyboardNewSettings = platform.defaultSettings;-- // New terminal settings for keyboard: turn off buffering (non-canonical mode), echo and key processing- // NOTE: ISIG controls if ^C and ^Z generate break signals or not- keyboardNewSettings.c_lflag &= ~(ICANON | ECHO | ISIG);- //keyboardNewSettings.c_iflag &= ~(ISTRIP | INLCR | ICRNL | IGNCR | IXON | IXOFF);- keyboardNewSettings.c_cc[VMIN] = 1;- keyboardNewSettings.c_cc[VTIME] = 0;-- // Set new keyboard settings (change occurs immediately)- tcsetattr(STDIN_FILENO, TCSANOW, &keyboardNewSettings);-- // Save old keyboard mode to restore it at the end- platform.defaultFileFlags = fcntl(STDIN_FILENO, F_GETFL, 0); // F_GETFL: Get the file access mode and the file status flags- fcntl(STDIN_FILENO, F_SETFL, platform.defaultFileFlags | O_NONBLOCK); // F_SETFL: Set the file status flags to the value specified-- // NOTE: If ioctl() returns -1, it means the call failed for some reason (error code set in errno)- int result = ioctl(STDIN_FILENO, KDGKBMODE, &platform.defaultKeyboardMode);-- // In case of failure, it could mean a remote keyboard is used (SSH)- if (result < 0) TRACELOG(LOG_WARNING, "RPI: Failed to change keyboard mode, an SSH keyboard is probably used");- else- {- // Reconfigure keyboard mode to get:- // - scancodes (K_RAW)- // - keycodes (K_MEDIUMRAW)- // - ASCII chars (K_XLATE)- // - UNICODE chars (K_UNICODE)- ioctl(STDIN_FILENO, KDSKBMODE, K_XLATE); // ASCII chars- }-- // Register keyboard restore when program finishes- atexit(RestoreKeyboard);-}--// Restore default keyboard input-static void RestoreKeyboard(void)-{- // Reset to default keyboard settings- tcsetattr(STDIN_FILENO, TCSANOW, &platform.defaultSettings);-- // Reconfigure keyboard to default mode- fcntl(STDIN_FILENO, F_SETFL, platform.defaultFileFlags);- ioctl(STDIN_FILENO, KDSKBMODE, platform.defaultKeyboardMode);-}--#if defined(SUPPORT_SSH_KEYBOARD_RPI)-// Process keyboard inputs-static void ProcessKeyboard(void)-{- #define MAX_KEYBUFFER_SIZE 32 // Max size in bytes to read-- // Keyboard input polling (fill keys[256] array with status)- int bufferByteCount = 0; // Bytes available on the buffer- char keysBuffer[MAX_KEYBUFFER_SIZE] = { 0 }; // Max keys to be read at a time-- // Read availables keycodes from stdin- bufferByteCount = read(STDIN_FILENO, keysBuffer, MAX_KEYBUFFER_SIZE); // POSIX system call-- // Reset pressed keys array (it will be filled below)- for (int i = 0; i < MAX_KEYBOARD_KEYS; i++)- {- CORE.Input.Keyboard.currentKeyState[i] = 0;- CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;- }-- // Fill all read bytes (looking for keys)- for (int i = 0; i < bufferByteCount; i++)- {- // NOTE: If (key == 0x1b), depending on next key, it could be a special keymap code!- // Up -> 1b 5b 41 / Left -> 1b 5b 44 / Right -> 1b 5b 43 / Down -> 1b 5b 42- if (keysBuffer[i] == 0x1b)- {- // Check if ESCAPE key has been pressed to stop program- if (bufferByteCount == 1) CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] = 1;- else- {- if (keysBuffer[i + 1] == 0x5b) // Special function key- {- if ((keysBuffer[i + 2] == 0x5b) || (keysBuffer[i + 2] == 0x31) || (keysBuffer[i + 2] == 0x32))- {- // Process special function keys (F1 - F12)- switch (keysBuffer[i + 3])- {- case 0x41: CORE.Input.Keyboard.currentKeyState[290] = 1; break; // raylib KEY_F1- case 0x42: CORE.Input.Keyboard.currentKeyState[291] = 1; break; // raylib KEY_F2- case 0x43: CORE.Input.Keyboard.currentKeyState[292] = 1; break; // raylib KEY_F3- case 0x44: CORE.Input.Keyboard.currentKeyState[293] = 1; break; // raylib KEY_F4- case 0x45: CORE.Input.Keyboard.currentKeyState[294] = 1; break; // raylib KEY_F5- case 0x37: CORE.Input.Keyboard.currentKeyState[295] = 1; break; // raylib KEY_F6- case 0x38: CORE.Input.Keyboard.currentKeyState[296] = 1; break; // raylib KEY_F7- case 0x39: CORE.Input.Keyboard.currentKeyState[297] = 1; break; // raylib KEY_F8- case 0x30: CORE.Input.Keyboard.currentKeyState[298] = 1; break; // raylib KEY_F9- case 0x31: CORE.Input.Keyboard.currentKeyState[299] = 1; break; // raylib KEY_F10- case 0x33: CORE.Input.Keyboard.currentKeyState[300] = 1; break; // raylib KEY_F11- case 0x34: CORE.Input.Keyboard.currentKeyState[301] = 1; break; // raylib KEY_F12- default: break;- }-- if (keysBuffer[i + 2] == 0x5b) i += 4;- else if ((keysBuffer[i + 2] == 0x31) || (keysBuffer[i + 2] == 0x32)) i += 5;- }- else- {- switch (keysBuffer[i + 2])- {- case 0x41: CORE.Input.Keyboard.currentKeyState[265] = 1; break; // raylib KEY_UP- case 0x42: CORE.Input.Keyboard.currentKeyState[264] = 1; break; // raylib KEY_DOWN- case 0x43: CORE.Input.Keyboard.currentKeyState[262] = 1; break; // raylib KEY_RIGHT- case 0x44: CORE.Input.Keyboard.currentKeyState[263] = 1; break; // raylib KEY_LEFT- default: break;- }-- i += 3; // Jump to next key- }-- // NOTE: Some keys are not directly keymapped (CTRL, ALT, SHIFT)- }- }- }- else if (keysBuffer[i] == 0x0a) // raylib KEY_ENTER (don't mix with <linux/input.h> KEY_*)- {- CORE.Input.Keyboard.currentKeyState[257] = 1;-- CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = 257; // Add keys pressed into queue- CORE.Input.Keyboard.keyPressedQueueCount++;- }- else if (keysBuffer[i] == 0x7f) // raylib KEY_BACKSPACE- {- CORE.Input.Keyboard.currentKeyState[259] = 1;-- CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = 257; // Add keys pressed into queue- CORE.Input.Keyboard.keyPressedQueueCount++;- }- else- {- // Translate lowercase a-z letters to A-Z- if ((keysBuffer[i] >= 97) && (keysBuffer[i] <= 122))- {- CORE.Input.Keyboard.currentKeyState[(int)keysBuffer[i] - 32] = 1;- }- else CORE.Input.Keyboard.currentKeyState[(int)keysBuffer[i]] = 1;-- CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keysBuffer[i]; // Add keys pressed into queue- CORE.Input.Keyboard.keyPressedQueueCount++;- }- }-- // Check exit key (same functionality as GLFW3 KeyCallback())- if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] == 1) CORE.Window.shouldClose = true;--#if defined(SUPPORT_SCREEN_CAPTURE)- // Check screen capture key (raylib key: KEY_F12)- if (CORE.Input.Keyboard.currentKeyState[301] == 1)- {- TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));- screenshotCounter++;- }-#endif-}-#endif // SUPPORT_SSH_KEYBOARD_RPI--// Initialise user input from evdev(/dev/input/event<N>)-// this means mouse, keyboard or gamepad devices-static void InitEvdevInput(void)-{- char path[MAX_FILEPATH_LENGTH] = { 0 };- DIR *directory = NULL;- struct dirent *entity = NULL;-- // Initialise keyboard file descriptor- platform.keyboardFd = -1;-- // Reset variables- for (int i = 0; i < MAX_TOUCH_POINTS; ++i)- {- CORE.Input.Touch.position[i].x = -1;- CORE.Input.Touch.position[i].y = -1;- }-- // Reset keyboard key state- for (int i = 0; i < MAX_KEYBOARD_KEYS; i++)- {- CORE.Input.Keyboard.currentKeyState[i] = 0;- CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;- }-- // Open the linux directory of "/dev/input"- directory = opendir(DEFAULT_EVDEV_PATH);-- if (directory)- {- while ((entity = readdir(directory)) != NULL)- {- if ((strncmp("event", entity->d_name, strlen("event")) == 0) || // Search for devices named "event*"- (strncmp("mouse", entity->d_name, strlen("mouse")) == 0)) // Search for devices named "mouse*"- {- sprintf(path, "%s%s", DEFAULT_EVDEV_PATH, entity->d_name);- ConfigureEvdevDevice(path); // Configure the device if appropriate- }- }-- closedir(directory);- }- else TRACELOG(LOG_WARNING, "RPI: Failed to open linux event directory: %s", DEFAULT_EVDEV_PATH);-}--// Identifies a input device and configures it for use if appropriate-static void ConfigureEvdevDevice(char *device)-{- #define BITS_PER_LONG (8*sizeof(long))- #define NBITS(x) ((((x) - 1)/BITS_PER_LONG) + 1)- #define OFF(x) ((x)%BITS_PER_LONG)- #define BIT(x) (1UL<<OFF(x))- #define LONG(x) ((x)/BITS_PER_LONG)- #define TEST_BIT(array, bit) ((array[LONG(bit)] >> OFF(bit)) & 1)-- struct input_absinfo absinfo = { 0 };- unsigned long evBits[NBITS(EV_MAX)] = { 0 };- unsigned long absBits[NBITS(ABS_MAX)] = { 0 };- unsigned long relBits[NBITS(REL_MAX)] = { 0 };- unsigned long keyBits[NBITS(KEY_MAX)] = { 0 };- bool hasAbs = false;- bool hasRel = false;- bool hasAbsMulti = false;- int freeWorkerId = -1;- int fd = -1;-- InputEventWorker *worker = NULL;-- // Open the device and allocate worker- //-------------------------------------------------------------------------------------------------------- // Find a free spot in the workers array- for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)- {- if (platform.eventWorker[i].threadId == 0)- {- freeWorkerId = i;- break;- }- }-- // Select the free worker from array- if (freeWorkerId >= 0)- {- worker = &(platform.eventWorker[freeWorkerId]); // Grab a pointer to the worker- memset(worker, 0, sizeof(InputEventWorker)); // Clear the worker- }- else- {- TRACELOG(LOG_WARNING, "RPI: Failed to create input device thread for %s, out of worker slots", device);- return;- }-- // Open the device- fd = open(device, O_RDONLY | O_NONBLOCK);- if (fd < 0)- {- TRACELOG(LOG_WARNING, "RPI: Failed to open input device: %s", device);- return;- }- worker->fd = fd;-- // Grab number on the end of the devices name "event<N>"- int devNum = 0;- char *ptrDevName = strrchr(device, 't');- worker->eventNum = -1;-- if (ptrDevName != NULL)- {- if (sscanf(ptrDevName, "t%d", &devNum) == 1) worker->eventNum = devNum;- }- else worker->eventNum = 0; // TODO: HACK: Grab number for mouse0 device!-- // At this point we have a connection to the device, but we don't yet know what the device is.- // It could be many things, even as simple as a power button...- //--------------------------------------------------------------------------------------------------------- // Identify the device- //-------------------------------------------------------------------------------------------------------- ioctl(fd, EVIOCGBIT(0, sizeof(evBits)), evBits); // Read a bitfield of the available device properties-- // Check for absolute input devices- if (TEST_BIT(evBits, EV_ABS))- {- ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits);-- // Check for absolute movement support (usually touchscreens, but also joysticks)- if (TEST_BIT(absBits, ABS_X) && TEST_BIT(absBits, ABS_Y))- {- hasAbs = true;-- // Get the scaling values- ioctl(fd, EVIOCGABS(ABS_X), &absinfo);- worker->absRange.x = absinfo.minimum;- worker->absRange.width = absinfo.maximum - absinfo.minimum;- platform.absRange.x = absinfo.minimum;- platform.absRange.width = absinfo.maximum - absinfo.minimum;-- ioctl(fd, EVIOCGABS(ABS_Y), &absinfo);- worker->absRange.y = absinfo.minimum;- worker->absRange.height = absinfo.maximum - absinfo.minimum;- platform.absRange.y = absinfo.minimum;- platform.absRange.height = absinfo.maximum - absinfo.minimum;- }-- // Check for multiple absolute movement support (usually multitouch touchscreens)- if (TEST_BIT(absBits, ABS_MT_POSITION_X) && TEST_BIT(absBits, ABS_MT_POSITION_Y))- {- hasAbsMulti = true;-- // Get the scaling values- ioctl(fd, EVIOCGABS(ABS_X), &absinfo);- worker->absRange.x = absinfo.minimum;- worker->absRange.width = absinfo.maximum - absinfo.minimum;- platform.absRange.x = absinfo.minimum;- platform.absRange.width = absinfo.maximum - absinfo.minimum;-- ioctl(fd, EVIOCGABS(ABS_Y), &absinfo);- worker->absRange.y = absinfo.minimum;- worker->absRange.height = absinfo.maximum - absinfo.minimum;- platform.absRange.y = absinfo.minimum;- platform.absRange.height = absinfo.maximum - absinfo.minimum;- }- }-- // Check for relative movement support (usually mouse)- if (TEST_BIT(evBits, EV_REL))- {- ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relBits)), relBits);-- if (TEST_BIT(relBits, REL_X) && TEST_BIT(relBits, REL_Y)) hasRel = true;- }-- // Check for button support to determine the device type(usually on all input devices)- if (TEST_BIT(evBits, EV_KEY))- {- ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits);-- if (hasAbs || hasAbsMulti)- {- if (TEST_BIT(keyBits, BTN_TOUCH)) worker->isTouch = true; // This is a touchscreen- if (TEST_BIT(keyBits, BTN_TOOL_FINGER)) worker->isTouch = true; // This is a drawing tablet- if (TEST_BIT(keyBits, BTN_TOOL_PEN)) worker->isTouch = true; // This is a drawing tablet- if (TEST_BIT(keyBits, BTN_STYLUS)) worker->isTouch = true; // This is a drawing tablet- if (worker->isTouch || hasAbsMulti) worker->isMultitouch = true; // This is a multitouch capable device- }-- if (hasRel)- {- if (TEST_BIT(keyBits, BTN_LEFT)) worker->isMouse = true; // This is a mouse- if (TEST_BIT(keyBits, BTN_RIGHT)) worker->isMouse = true; // This is a mouse- }-- if (TEST_BIT(keyBits, BTN_A)) worker->isGamepad = true; // This is a gamepad- if (TEST_BIT(keyBits, BTN_TRIGGER)) worker->isGamepad = true; // This is a gamepad- if (TEST_BIT(keyBits, BTN_START)) worker->isGamepad = true; // This is a gamepad- if (TEST_BIT(keyBits, BTN_TL)) worker->isGamepad = true; // This is a gamepad- if (TEST_BIT(keyBits, BTN_TL)) worker->isGamepad = true; // This is a gamepad-- if (TEST_BIT(keyBits, KEY_SPACE)) worker->isKeyboard = true; // This is a keyboard- }- //--------------------------------------------------------------------------------------------------------- // Decide what to do with the device- //-------------------------------------------------------------------------------------------------------- if (worker->isKeyboard && (platform.keyboardFd == -1))- {- // Use the first keyboard encountered. This assumes that a device that says it's a keyboard is just a- // keyboard. The keyboard is polled synchronously, whereas other input devices are polled in separate- // threads so that they don't drop events when the frame rate is slow.- TRACELOG(LOG_INFO, "RPI: Opening keyboard device: %s", device);- platform.keyboardFd = worker->fd;- }- else if (worker->isTouch || worker->isMouse)- {- // Looks like an interesting device- TRACELOG(LOG_INFO, "RPI: Opening input device: %s (%s%s%s%s)", device,- worker->isMouse? "mouse " : "",- worker->isMultitouch? "multitouch " : "",- worker->isTouch? "touchscreen " : "",- worker->isGamepad? "gamepad " : "");- platform.mouseFd = worker->fd;-- // NOTE: moved the mouse/touch/gesture input to PollInputEvents()/- // so added the "platform.mouseFd = worker->fd;" line above- // and commented the thread code below:-- // Create a thread for this device- //int error = pthread_create(&worker->threadId, NULL, &EventThread, (void *)worker);- //if (error != 0)- //{- // TRACELOG(LOG_WARNING, "RPI: Failed to create input device thread: %s (error: %d)", device, error);- // worker->threadId = 0;- // close(fd);- //}--#if defined(USE_LAST_TOUCH_DEVICE)- // Find touchscreen with the highest index- int maxTouchNumber = -1;-- for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)- {- if (platform.eventWorker[i].isTouch && (platform.eventWorker[i].eventNum > maxTouchNumber)) maxTouchNumber = platform.eventWorker[i].eventNum;- }-- // Find touchscreens with lower indexes- for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)- {- if (platform.eventWorker[i].isTouch && (platform.eventWorker[i].eventNum < maxTouchNumber))- {- if (platform.eventWorker[i].threadId != 0)- {- TRACELOG(LOG_WARNING, "RPI: Found duplicate touchscreen, killing touchscreen on event: %d", i);- pthread_cancel(platform.eventWorker[i].threadId);- close(platform.eventWorker[i].fd);- }- }- }-#endif- }- else close(fd); // We are not interested in this device- //--------------------------------------------------------------------------------------------------------}--// Poll and process evdev keyboard events-static void PollKeyboardEvents(void)-{- int fd = platform.keyboardFd;- if (fd == -1) return;-- struct input_event event = { 0 };- int keycode = -1;-- // Try to read data from the keyboard and only continue if successful- while (read(fd, &event, sizeof(event)) == (int)sizeof(event))- {- // Button parsing- if (event.type == EV_KEY)- {-#if defined(SUPPORT_SSH_KEYBOARD_RPI)- // Change keyboard mode to events- platform.eventKeyboardMode = true;-#endif- // Keyboard button parsing- if ((event.code >= 1) && (event.code <= 255)) //Keyboard keys appear for codes 1 to 255- {- keycode = keymapUS[event.code & 0xFF]; // The code we get is a scancode so we look up the appropriate keycode-- // Make sure we got a valid keycode- if ((keycode > 0) && (keycode < sizeof(CORE.Input.Keyboard.currentKeyState)))- {- // WARNING: https://www.kernel.org/doc/Documentation/input/input.txt- // Event interface: 'value' is the value the event carries. Either a relative change for EV_REL,- // absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat- CORE.Input.Keyboard.currentKeyState[keycode] = (event.value >= 1)? 1 : 0;- CORE.Input.Keyboard.keyRepeatInFrame[keycode] = (event.value == 2)? 1 : 0;- if (event.value >= 1)- {- CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; // Register last key pressed- CORE.Input.Keyboard.keyPressedQueueCount++;- }-- #if defined(SUPPORT_SCREEN_CAPTURE)- // Check screen capture key (raylib key: KEY_F12)- if (CORE.Input.Keyboard.currentKeyState[301] == 1)- {- TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));- screenshotCounter++;- }- #endif-- // Detect char presses (unicode)- if (event.value == 1)- {- // Check if there is space available in the queue- if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE)- {- // Add character to the queue- CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = EvkeyToUnicodeLUT[event.code];- CORE.Input.Keyboard.charPressedQueueCount++;- }- }-- if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] == 1) CORE.Window.shouldClose = true;-- TRACELOGD("RPI: KEY_%s ScanCode: %4i KeyCode: %4i", (event.value == 0)? "UP" : "DOWN", event.code, keycode);- }- }- }- }-}--// Input device events reading thread-static void *EventThread(void *arg)-{-/*- struct input_event event = { 0 };- InputEventWorker *worker = (InputEventWorker *)arg;-- int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE- bool gestureUpdate = false; // Flag to note gestures require to update-- while (!CORE.Window.shouldClose)- {- // Try to read data from the device and only continue if successful- while (read(worker->fd, &event, sizeof(event)) == (int)sizeof(event))- {- // Relative movement parsing- if (event.type == EV_REL)- {- if (event.code == REL_X)- {- if (platform.cursorRelative)- {- CORE.Input.Mouse.currentPosition.x -= event.value;- CORE.Input.Touch.position[0].x = CORE.Input.Mouse.currentPosition.x;- }- else- {- CORE.Input.Mouse.currentPosition.x += event.value;- CORE.Input.Touch.position[0].x = CORE.Input.Mouse.currentPosition.x;- }-- touchAction = 2; // TOUCH_ACTION_MOVE- gestureUpdate = true;- }-- if (event.code == REL_Y)- {- if (platform.cursorRelative)- {- CORE.Input.Mouse.currentPosition.y -= event.value;- CORE.Input.Touch.position[0].y = CORE.Input.Mouse.currentPosition.y;- }- else- {- CORE.Input.Mouse.currentPosition.y += event.value;- CORE.Input.Touch.position[0].y = CORE.Input.Mouse.currentPosition.y;- }-- touchAction = 2; // TOUCH_ACTION_MOVE- gestureUpdate = true;- }-- if (event.code == REL_WHEEL) platform.eventWheelMove.y += event.value;- }-- // Absolute movement parsing- if (event.type == EV_ABS)- {- // Basic movement- if (event.code == ABS_X)- {- CORE.Input.Mouse.currentPosition.x = (event.value - worker->absRange.x)*CORE.Window.screen.width/worker->absRange.width; // Scale according to absRange- CORE.Input.Touch.position[0].x = (event.value - worker->absRange.x)*CORE.Window.screen.width/worker->absRange.width; // Scale according to absRange-- touchAction = 2; // TOUCH_ACTION_MOVE- gestureUpdate = true;- }-- if (event.code == ABS_Y)- {- CORE.Input.Mouse.currentPosition.y = (event.value - worker->absRange.y)*CORE.Window.screen.height/worker->absRange.height; // Scale according to absRange- CORE.Input.Touch.position[0].y = (event.value - worker->absRange.y)*CORE.Window.screen.height/worker->absRange.height; // Scale according to absRange-- touchAction = 2; // TOUCH_ACTION_MOVE- gestureUpdate = true;- }-- // Multitouch movement- if (event.code == ABS_MT_SLOT) worker->touchSlot = event.value; // Remember the slot number for the folowing events-- if (event.code == ABS_MT_POSITION_X)- {- if (worker->touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[worker->touchSlot].x = (event.value - worker->absRange.x)*CORE.Window.screen.width/worker->absRange.width; // Scale according to absRange- }-- if (event.code == ABS_MT_POSITION_Y)- {- if (worker->touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[worker->touchSlot].y = (event.value - worker->absRange.y)*CORE.Window.screen.height/worker->absRange.height; // Scale according to absRange- }-- if (event.code == ABS_MT_TRACKING_ID)- {- if ((event.value < 0) && (worker->touchSlot < MAX_TOUCH_POINTS))- {- // Touch has ended for this point- CORE.Input.Touch.position[worker->touchSlot].x = -1;- CORE.Input.Touch.position[worker->touchSlot].y = -1;- }- }-- // Touchscreen tap- if (event.code == ABS_PRESSURE)- {- int previousMouseLeftButtonState = platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT];-- if (!event.value && previousMouseLeftButtonState)- {- platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0;-- touchAction = 0; // TOUCH_ACTION_UP- gestureUpdate = true;- }-- if (event.value && !previousMouseLeftButtonState)- {- platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 1;-- touchAction = 1; // TOUCH_ACTION_DOWN- gestureUpdate = true;- }- }-- }-- // Button parsing- if (event.type == EV_KEY)- {- // Mouse button parsing- if ((event.code == BTN_TOUCH) || (event.code == BTN_LEFT))- {- platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = event.value;-- if (event.value > 0) touchAction = 1; // TOUCH_ACTION_DOWN- else touchAction = 0; // TOUCH_ACTION_UP- gestureUpdate = true;- }-- if (event.code == BTN_RIGHT) platform.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value;- if (event.code == BTN_MIDDLE) platform.currentButtonStateEvdev[MOUSE_BUTTON_MIDDLE] = event.value;- if (event.code == BTN_SIDE) platform.currentButtonStateEvdev[MOUSE_BUTTON_SIDE] = event.value;- if (event.code == BTN_EXTRA) platform.currentButtonStateEvdev[MOUSE_BUTTON_EXTRA] = event.value;- if (event.code == BTN_FORWARD) platform.currentButtonStateEvdev[MOUSE_BUTTON_FORWARD] = event.value;- if (event.code == BTN_BACK) platform.currentButtonStateEvdev[MOUSE_BUTTON_BACK] = event.value;- }-- // Screen confinement- if (!CORE.Input.Mouse.cursorHidden)- {- if (CORE.Input.Mouse.currentPosition.x < 0) CORE.Input.Mouse.currentPosition.x = 0;- if (CORE.Input.Mouse.currentPosition.x > CORE.Window.screen.width/CORE.Input.Mouse.scale.x) CORE.Input.Mouse.currentPosition.x = CORE.Window.screen.width/CORE.Input.Mouse.scale.x;-- if (CORE.Input.Mouse.currentPosition.y < 0) CORE.Input.Mouse.currentPosition.y = 0;- if (CORE.Input.Mouse.currentPosition.y > CORE.Window.screen.height/CORE.Input.Mouse.scale.y) CORE.Input.Mouse.currentPosition.y = CORE.Window.screen.height/CORE.Input.Mouse.scale.y;- }-- // Update touch point count- CORE.Input.Touch.pointCount = 0;- for (int i = 0; i < MAX_TOUCH_POINTS; i++)- {- if (CORE.Input.Touch.position[i].x >= 0) CORE.Input.Touch.pointCount++;- }--#if defined(SUPPORT_GESTURES_SYSTEM)- if (gestureUpdate)- {- GestureEvent gestureEvent = { 0 };-- gestureEvent.touchAction = touchAction;- gestureEvent.pointCount = CORE.Input.Touch.pointCount;-- for (int i = 0; i < MAX_TOUCH_POINTS; i++)- {- gestureEvent.pointId[i] = i;- gestureEvent.position[i] = CORE.Input.Touch.position[i];- }-- ProcessGestureEvent(gestureEvent);- }-#endif- }-- WaitTime(0.005); // Sleep for 5ms to avoid hogging CPU time- }-- close(worker->fd);-*/- return NULL;-}--// Initialize gamepad system-static void InitGamepad(void)-{- char gamepadDev[128] = { 0 };-- for (int i = 0; i < MAX_GAMEPADS; i++)- {- sprintf(gamepadDev, "%s%i", DEFAULT_GAMEPAD_DEV, i);-- if ((platform.gamepadStreamFd[i] = open(gamepadDev, O_RDONLY | O_NONBLOCK)) < 0)- {- // NOTE: Only show message for first gamepad- if (i == 0) TRACELOG(LOG_WARNING, "RPI: Failed to open Gamepad device, no gamepad available");- }- else- {- CORE.Input.Gamepad.ready[i] = true;-- // NOTE: Only show message for first gamepad- if (i == 0) TRACELOG(LOG_INFO, "RPI: Gamepad device initialized successfully");-- ioctl(platform.gamepadStreamFd[i], JSIOCGNAME(64), &CORE.Input.Gamepad.name[i]);- ioctl(platform.gamepadStreamFd[i], JSIOCGAXES, &CORE.Input.Gamepad.axisCount[i]);- }- }-}--// Process Gamepad (/dev/input/js0)-static void PollGamepadEvents(void)-{- #define JS_EVENT_BUTTON 0x01 // Button pressed/released- #define JS_EVENT_AXIS 0x02 // Joystick axis moved- #define JS_EVENT_INIT 0x80 // Initial state of device-- struct js_event {- unsigned int time; // event timestamp in milliseconds- short value; // event value- unsigned char type; // event type- unsigned char number; // event axis/button number- };-- // Read gamepad event- struct js_event gamepadEvent = { 0 };-- for (int i = 0; i < MAX_GAMEPADS; i++)- {- if (CORE.Input.Gamepad.ready[i])- {- // Register previous gamepad states- for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k];-- while (read(platform.gamepadStreamFd[i], &gamepadEvent, sizeof(struct js_event)) == (int)sizeof(struct js_event))- {- gamepadEvent.type &= ~JS_EVENT_INIT; // Ignore synthetic events-- // Process gamepad events by type- if (gamepadEvent.type == JS_EVENT_BUTTON)- {- TRACELOG(LOG_DEBUG, "RPI: Gamepad %i button: %i, value: %i", i, gamepadEvent.number, gamepadEvent.value);-- if (gamepadEvent.number < MAX_GAMEPAD_BUTTONS)- {- // 1 - button pressed, 0 - button released- CORE.Input.Gamepad.currentButtonState[i][gamepadEvent.number] = (int)gamepadEvent.value;-- if ((int)gamepadEvent.value == 1) CORE.Input.Gamepad.lastButtonPressed = gamepadEvent.number;- else CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN- }- }- else if (gamepadEvent.type == JS_EVENT_AXIS)- {- TRACELOG(LOG_DEBUG, "RPI: Gamepad %i axis: %i, value: %i", i, gamepadEvent.number, gamepadEvent.value);-- if (gamepadEvent.number < MAX_GAMEPAD_AXIS)- {- // NOTE: Scaling of gamepadEvent.value to get values between -1..1- CORE.Input.Gamepad.axisState[i][gamepadEvent.number] = (float)gamepadEvent.value/32768;- }- }- }- }+// WARNING: Both 'linux/input.h' and 'raylib.h' define KEY_F12+// To avoid conflict with the capturing code in rcore.c we undefine the macro KEY_F12,+// so the enum KEY_F12 from raylib is used+#undef KEY_F12++#include <gbm.h> // Generic Buffer Management (native platform for EGL on DRM)+#include <xf86drm.h> // Direct Rendering Manager user-level library interface+#include <xf86drmMode.h> // Direct Rendering Manager mode setting (KMS) interface++#include "EGL/egl.h" // Native platform windowing system interface+#include "EGL/eglext.h" // EGL extensions++#ifndef EGL_OPENGL_ES3_BIT+ #define EGL_OPENGL_ES3_BIT 0x40+#endif++//----------------------------------------------------------------------------------+// Defines and Macros+//----------------------------------------------------------------------------------+#define USE_LAST_TOUCH_DEVICE // When multiple touchscreens are connected, only use the one with the highest event<N> number++#define DEFAULT_EVDEV_PATH "/dev/input/" // Path to the linux input events++// So actually the biggest key is KEY_CNT but we only really map the keys up to+// KEY_ALS_TOGGLE+#define KEYMAP_SIZE KEY_ALS_TOGGLE++//----------------------------------------------------------------------------------+// Types and Structures Definition+//----------------------------------------------------------------------------------++typedef struct {+ // Display data+ int fd; // File descriptor for /dev/dri/...+ drmModeConnector *connector; // Direct Rendering Manager (DRM) mode connector+ drmModeCrtc *crtc; // CRT Controller+ int modeIndex; // Index of the used mode of connector->modes+ struct gbm_device *gbmDevice; // GBM device+ struct gbm_surface *gbmSurface; // GBM surface+ struct gbm_bo *prevBO; // Previous GBM buffer object (during frame swapping)+ uint32_t prevFB; // Previous GBM framebufer (during frame swapping)++ EGLDisplay device; // Native display device (physical screen connection)+ EGLSurface surface; // Surface to draw on, framebuffers (connected to context)+ EGLContext context; // Graphic context, mode in which drawing can be done+ EGLConfig config; // Graphic config++ // Keyboard data+ int defaultKeyboardMode; // Default keyboard mode+ bool eventKeyboardMode; // Keyboard in event mode+ int defaultFileFlags; // Default IO file flags+ struct termios defaultSettings; // Default keyboard settings+ int keyboardFd; // File descriptor for the evdev keyboard++ // Mouse data+ Vector2 eventWheelMove; // Registers the event mouse wheel variation+ // NOTE: currentButtonState[] can't be written directly due to multithreading, app could miss the update+ char currentButtonStateEvdev[MAX_MOUSE_BUTTONS]; // Holds the new mouse state for the next polling event to grab+ bool cursorRelative; // Relative cursor mode+ int mouseFd; // File descriptor for the evdev mouse/touch/gestures+ Rectangle absRange; // Range of values for absolute pointing devices (touchscreens)+ int touchSlot; // Hold the touch slot number of the currently being sent multitouch block++ // Gamepad data+ int gamepadStreamFd[MAX_GAMEPADS]; // Gamepad device file descriptor+ int gamepadAbsAxisRange[MAX_GAMEPADS][MAX_GAMEPAD_AXIS][2]; // [0] = min, [1] = range value of the axis+ int gamepadAbsAxisMap[MAX_GAMEPADS][ABS_CNT]; // Maps the axes gamepads from the evdev api to a sequential one+ int gamepadCount; // The number of gamepads registered+} PlatformData;++//----------------------------------------------------------------------------------+// Global Variables Definition+//----------------------------------------------------------------------------------+extern CoreData CORE; // Global CORE state context++static PlatformData platform = { 0 }; // Platform specific data++//----------------------------------------------------------------------------------+// Local Variables Definition+//----------------------------------------------------------------------------------++// NOTE: The complete evdev EV_KEY list can be found at /usr/include/linux/input-event-codes.h+// TODO: Complete the LUT with all unicode decimal values+// TODO: Replace this with a keymap from the X11 to get the correct regional map for the keyboard:+// Currently non US keyboards will have the wrong mapping for some keys+// NOTE: Replacing this with the keymap from X11 would probably be useless, as people use the drm+// backend to *avoid* X11+static const int evkeyToUnicodeLUT[] = {+ 0, 27, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 8, 0, 113, 119, 101, 114,+ 116, 121, 117, 105, 111, 112, 0, 0, 13, 0, 97, 115, 100, 102, 103, 104, 106, 107, 108, 59,+ 39, 96, 0, 92, 122, 120, 99, 118, 98, 110, 109, 44, 46, 47, 0, 0, 0, 32+ // LUT currently incomplete, just mapped the most essential keys+};++// This is the map used to map any keycode returned from linux to a raylib code from 'raylib.h'+// NOTE: Use short here to save a little memory+static const short linuxToRaylibMap[KEYMAP_SIZE] = {+ // We don't map those with designated initialization, because we would getting+ // into loads of naming conflicts+ 0, 256, 49, 50, 51, 52, 53, 54,+ 55, 56, 57, 48, 45, 61, 259, 258,+ 81, 87, 69, 82, 84, 89, 85, 73,+ 79, 80, 91, 93, 257, 341, 65, 83,+ 68, 70, 71, 72, 74, 75, 76, 59,+ 39, 96, 340, 92, 90, 88, 67, 86,+ 66, 78, 77, 44, 46, 47, 344, 332,+ 342, 32, 280, 290, 291, 292, 293, 294,+ 295, 296, 297, 298, 299, 282, 281, 327,+ 328, 329, 333, 324, 325, 326, 334, 321,+ 322, 323, 320, 330, 0, 85, 86, 300,+ 301, 89, 90, 91, 92, 93, 94, 95,+ 335, 345, 331, 283, 346, 101, 268, 265,+ 266, 263, 262, 269, 264, 267, 260, 261,+ 112, 113, 114, 115, 116, 117, 118, 119,+ 120, 121, 122, 123, 124, 125, 347, 127,+ 128, 129, 130, 131, 132, 133, 134, 135,+ 136, 137, 138, 139, 140, 141, 142, 143,+ 144, 145, 146, 147, 148, 149, 150, 151,+ 152, 153, 154, 155, 156, 157, 158, 159,+ 160, 161, 162, 163, 164, 165, 166, 167,+ 168, 169, 170, 171, 172, 173, 174, 175,+ 176, 177, 178, 179, 180, 181, 182, 183,+ 184, 185, 186, 187, 188, 189, 190, 191,+ 192, 193, 194, 0, 0, 0, 0, 0,+ 200, 201, 202, 203, 204, 205, 206, 207,+ 208, 209, 210, 211, 212, 213, 214, 215,+ 216, 217, 218, 219, 220, 221, 222, 223,+ 224, 225, 226, 227, 228, 229, 230, 231,+ 232, 233, 234, 235, 236, 237, 238, 239,+ 240, 241, 242, 243, 244, 245, 246, 247,+ 248, 0, 0, 0, 0, 0, 0, 0,++ // Gamepads are mapped according to:+ // https://www.kernel.org/doc/html/next/input/gamepad.html+ // Those mappings are standardized, but that doesn't mean people follow+ // the standards, so this is more of an approximation+ [BTN_DPAD_UP] = GAMEPAD_BUTTON_LEFT_FACE_UP,+ [BTN_DPAD_RIGHT] = GAMEPAD_BUTTON_LEFT_FACE_RIGHT,+ [BTN_DPAD_DOWN] = GAMEPAD_BUTTON_LEFT_FACE_DOWN,+ [BTN_DPAD_LEFT] = GAMEPAD_BUTTON_LEFT_FACE_LEFT,+ [BTN_Y] = GAMEPAD_BUTTON_RIGHT_FACE_UP,+ [BTN_B] = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT,+ [BTN_A] = GAMEPAD_BUTTON_RIGHT_FACE_DOWN,+ [BTN_X] = GAMEPAD_BUTTON_RIGHT_FACE_LEFT,+ [BTN_TL] = GAMEPAD_BUTTON_LEFT_TRIGGER_1,+ [BTN_TL2] = GAMEPAD_BUTTON_LEFT_TRIGGER_2,+ [BTN_TR] = GAMEPAD_BUTTON_RIGHT_TRIGGER_1,+ [BTN_TR2] GAMEPAD_BUTTON_RIGHT_TRIGGER_2,+ [BTN_SELECT] = GAMEPAD_BUTTON_MIDDLE_LEFT,+ [BTN_MODE] = GAMEPAD_BUTTON_MIDDLE,+ [BTN_START] = GAMEPAD_BUTTON_MIDDLE_RIGHT,+ [BTN_THUMBL] = GAMEPAD_BUTTON_LEFT_THUMB,+ [BTN_THUMBR] = GAMEPAD_BUTTON_RIGHT_THUMB,+};++//----------------------------------------------------------------------------------+// Module Internal Functions Declaration+//----------------------------------------------------------------------------------+int InitPlatform(void); // Initialize platform (graphics, inputs and more)+void ClosePlatform(void); // Close platform++#if defined(SUPPORT_SSH_KEYBOARD_RPI)+static void InitKeyboard(void); // Initialize raw keyboard system+static void RestoreKeyboard(void); // Restore keyboard system+static void ProcessKeyboard(void); // Process keyboard events+#endif++static void InitEvdevInput(void); // Initialize evdev inputs+static void ConfigureEvdevDevice(char *device); // Identifies a input device and configures it for use if appropriate+static void PollKeyboardEvents(void); // Process evdev keyboard events+static void PollGamepadEvents(void); // Process evdev gamepad events+static void PollMouseEvents(void); // Process evdev mouse events++static int FindMatchingConnectorMode(const drmModeConnector *connector, const drmModeModeInfo *mode); // Search matching DRM mode in connector's mode list+static int FindExactConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search exactly matching DRM connector mode in connector's list+static int FindNearestConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search the nearest matching DRM connector mode in connector's list++//----------------------------------------------------------------------------------+// Module Functions Declaration+//----------------------------------------------------------------------------------+// NOTE: Functions declaration is provided by raylib.h++//----------------------------------------------------------------------------------+// Module Functions Definition: Window and Graphics Device+//----------------------------------------------------------------------------------++// Check if application should close+// NOTE: By default, if KEY_ESCAPE pressed+bool WindowShouldClose(void)+{+ if (CORE.Window.ready) return CORE.Window.shouldClose;+ else return true;+}++// Toggle fullscreen mode+void ToggleFullscreen(void)+{+ TRACELOG(LOG_WARNING, "ToggleFullscreen() not available on target platform");+}++// Toggle borderless windowed mode+void ToggleBorderlessWindowed(void)+{+ TRACELOG(LOG_WARNING, "ToggleBorderlessWindowed() not available on target platform");+}++// Set window state: maximized, if resizable+void MaximizeWindow(void)+{+ TRACELOG(LOG_WARNING, "MaximizeWindow() not available on target platform");+}++// Set window state: minimized+void MinimizeWindow(void)+{+ TRACELOG(LOG_WARNING, "MinimizeWindow() not available on target platform");+}++// Set window state: not minimized/maximized+void RestoreWindow(void)+{+ TRACELOG(LOG_WARNING, "RestoreWindow() not available on target platform");+}++// Set window configuration state using flags+void SetWindowState(unsigned int flags)+{+ TRACELOG(LOG_WARNING, "SetWindowState() not available on target platform");+}++// Clear window configuration state flags+void ClearWindowState(unsigned int flags)+{+ TRACELOG(LOG_WARNING, "ClearWindowState() not available on target platform");+}++// Set icon for window+void SetWindowIcon(Image image)+{+ TRACELOG(LOG_WARNING, "SetWindowIcon() not available on target platform");+}++// Set icon for window+void SetWindowIcons(Image *images, int count)+{+ TRACELOG(LOG_WARNING, "SetWindowIcons() not available on target platform");+}++// Set title for window+void SetWindowTitle(const char *title)+{+ CORE.Window.title = title;+}++// Set window position on screen (windowed mode)+void SetWindowPosition(int x, int y)+{+ TRACELOG(LOG_WARNING, "SetWindowPosition() not available on target platform");+}++// Set monitor for the current window+void SetWindowMonitor(int monitor)+{+ TRACELOG(LOG_WARNING, "SetWindowMonitor() not available on target platform");+}++// Set window minimum dimensions (FLAG_WINDOW_RESIZABLE)+void SetWindowMinSize(int width, int height)+{+ CORE.Window.screenMin.width = width;+ CORE.Window.screenMin.height = height;+}++// Set window maximum dimensions (FLAG_WINDOW_RESIZABLE)+void SetWindowMaxSize(int width, int height)+{+ CORE.Window.screenMax.width = width;+ CORE.Window.screenMax.height = height;+}++// Set window dimensions+void SetWindowSize(int width, int height)+{+ TRACELOG(LOG_WARNING, "SetWindowSize() not available on target platform");+}++// Set window opacity, value opacity is between 0.0 and 1.0+void SetWindowOpacity(float opacity)+{+ TRACELOG(LOG_WARNING, "SetWindowOpacity() not available on target platform");+}++// Set window focused+void SetWindowFocused(void)+{+ TRACELOG(LOG_WARNING, "SetWindowFocused() not available on target platform");+}++// Get native window handle+void *GetWindowHandle(void)+{+ TRACELOG(LOG_WARNING, "GetWindowHandle() not implemented on target platform");+ return NULL;+}++// Get number of monitors+int GetMonitorCount(void)+{+ TRACELOG(LOG_WARNING, "GetMonitorCount() not implemented on target platform");+ return 1;+}++// Get number of monitors+int GetCurrentMonitor(void)+{+ TRACELOG(LOG_WARNING, "GetCurrentMonitor() not implemented on target platform");+ return 0;+}++// Get selected monitor position+Vector2 GetMonitorPosition(int monitor)+{+ TRACELOG(LOG_WARNING, "GetMonitorPosition() not implemented on target platform");+ return (Vector2){ 0, 0 };+}++// Get selected monitor width (currently used by monitor)+int GetMonitorWidth(int monitor)+{+ TRACELOG(LOG_WARNING, "GetMonitorWidth() not implemented on target platform");+ return 0;+}++// Get selected monitor height (currently used by monitor)+int GetMonitorHeight(int monitor)+{+ TRACELOG(LOG_WARNING, "GetMonitorHeight() not implemented on target platform");+ return 0;+}++// Get selected monitor physical width in millimetres+int GetMonitorPhysicalWidth(int monitor)+{+ TRACELOG(LOG_WARNING, "GetMonitorPhysicalWidth() not implemented on target platform");+ return 0;+}++// Get selected monitor physical height in millimetres+int GetMonitorPhysicalHeight(int monitor)+{+ TRACELOG(LOG_WARNING, "GetMonitorPhysicalHeight() not implemented on target platform");+ return 0;+}++// Get selected monitor refresh rate+int GetMonitorRefreshRate(int monitor)+{+ int refresh = 0;++ if ((platform.connector) && (platform.modeIndex >= 0))+ {+ refresh = platform.connector->modes[platform.modeIndex].vrefresh;+ }++ return refresh;+}++// Get the human-readable, UTF-8 encoded name of the selected monitor+const char *GetMonitorName(int monitor)+{+ TRACELOG(LOG_WARNING, "GetMonitorName() not implemented on target platform");+ return "";+}++// Get window position XY on monitor+Vector2 GetWindowPosition(void)+{+ return (Vector2){ 0, 0 };+}++// Get window scale DPI factor for current monitor+Vector2 GetWindowScaleDPI(void)+{+ return (Vector2){ 1.0f, 1.0f };+}++// Set clipboard text content+void SetClipboardText(const char *text)+{+ TRACELOG(LOG_WARNING, "SetClipboardText() not implemented on target platform");+}++// Get clipboard text content+// NOTE: returned string is allocated and freed by GLFW+const char *GetClipboardText(void)+{+ TRACELOG(LOG_WARNING, "GetClipboardText() not implemented on target platform");+ return NULL;+}++// Show mouse cursor+void ShowCursor(void)+{+ CORE.Input.Mouse.cursorHidden = false;+}++// Hides mouse cursor+void HideCursor(void)+{+ CORE.Input.Mouse.cursorHidden = true;+}++// Enables cursor (unlock cursor)+void EnableCursor(void)+{+ // Set cursor position in the middle+ SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);++ platform.cursorRelative = false;+ CORE.Input.Mouse.cursorHidden = false;+}++// Disables cursor (lock cursor)+void DisableCursor(void)+{+ // Set cursor position in the middle+ SetMousePosition(0, 0);++ platform.cursorRelative = true;+ CORE.Input.Mouse.cursorHidden = true;+}++// Swap back buffer with front buffer (screen drawing)+void SwapScreenBuffer(void)+{+ eglSwapBuffers(platform.device, platform.surface);++ if (!platform.gbmSurface || (-1 == platform.fd) || !platform.connector || !platform.crtc) TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap");++ struct gbm_bo *bo = gbm_surface_lock_front_buffer(platform.gbmSurface);+ if (!bo) TRACELOG(LOG_ERROR, "DISPLAY: Failed GBM to lock front buffer");++ uint32_t fb = 0;+ int result = drmModeAddFB(platform.fd, platform.connector->modes[platform.modeIndex].hdisplay, platform.connector->modes[platform.modeIndex].vdisplay, 24, 32, gbm_bo_get_stride(bo), gbm_bo_get_handle(bo).u32, &fb);+ if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeAddFB() failed with result: %d", result);++ result = drmModeSetCrtc(platform.fd, platform.crtc->crtc_id, fb, 0, 0, &platform.connector->connector_id, 1, &platform.connector->modes[platform.modeIndex]);+ if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeSetCrtc() failed with result: %d", result);++ if (platform.prevFB)+ {+ result = drmModeRmFB(platform.fd, platform.prevFB);+ if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeRmFB() failed with result: %d", result);+ }++ platform.prevFB = fb;++ if (platform.prevBO) gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);++ platform.prevBO = bo;+}++//----------------------------------------------------------------------------------+// Module Functions Definition: Misc+//----------------------------------------------------------------------------------++// Get elapsed time measure in seconds since InitTimer()+double GetTime(void)+{+ double time = 0.0;+ struct timespec ts = { 0 };+ clock_gettime(CLOCK_MONOTONIC, &ts);+ unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;++ time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()++ return time;+}++// Open URL with default system browser (if available)+// NOTE: This function is only safe to use if you control the URL given.+// A user could craft a malicious string performing another action.+// Only call this function yourself not with user input or make sure to check the string yourself.+// Ref: https://github.com/raysan5/raylib/issues/686+void OpenURL(const char *url)+{+ TRACELOG(LOG_WARNING, "OpenURL() not implemented on target platform");+}++//----------------------------------------------------------------------------------+// Module Functions Definition: Inputs+//----------------------------------------------------------------------------------++// Set internal gamepad mappings+int SetGamepadMappings(const char *mappings)+{+ TRACELOG(LOG_WARNING, "SetGamepadMappings() not implemented on target platform");+ return 0;+}++// Set gamepad vibration+void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)+{+ TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform");+}++// Set mouse position XY+void SetMousePosition(int x, int y)+{+ CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };+ CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;+}++// Set mouse cursor+void SetMouseCursor(int cursor)+{+ TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform");+}++// Register all input events+void PollInputEvents(void)+{+#if defined(SUPPORT_GESTURES_SYSTEM)+ // NOTE: Gestures update must be called every frame to reset gestures correctly+ // because ProcessGestureEvent() is just called on an event, not every frame+ UpdateGestures();+#endif++ // Reset keys/chars pressed registered+ CORE.Input.Keyboard.keyPressedQueueCount = 0;+ CORE.Input.Keyboard.charPressedQueueCount = 0;++ // Reset last gamepad button/axis registered state+ CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN+ //CORE.Input.Gamepad.axisCount = 0;++ // Register previous keys states+ for (int i = 0; i < MAX_KEYBOARD_KEYS; i++)+ {+ CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];+ CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;+ }++ PollKeyboardEvents();++#if defined(SUPPORT_SSH_KEYBOARD_RPI)+ // NOTE: Keyboard reading could be done using input_event(s) or just read from stdin, both methods are used here.+ // stdin reading is still used for legacy purposes, it allows keyboard input trough SSH console+ if (!platform.eventKeyboardMode) ProcessKeyboard();+#endif++ // Check exit key+ if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] == 1) CORE.Window.shouldClose = true;++ // Register previous mouse position+ if (platform.cursorRelative) CORE.Input.Mouse.currentPosition = (Vector2){ 0.0f, 0.0f };+ else CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;++ // Register previous mouse states+ CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove;+ CORE.Input.Mouse.currentWheelMove = platform.eventWheelMove;+ platform.eventWheelMove = (Vector2){ 0.0f, 0.0f };++ for (int i = 0; i < MAX_MOUSE_BUTTONS; i++)+ {+ CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];+ CORE.Input.Mouse.currentButtonState[i] = platform.currentButtonStateEvdev[i];+ CORE.Input.Touch.currentTouchState[i] = platform.currentButtonStateEvdev[i];+ }++ // Register gamepads buttons events+ PollGamepadEvents();++ // Register previous touch states+ for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i];++ // Reset touch positions+ //for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ 0, 0 };++ // Map touch position to mouse position for convenience+ CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;++ // Handle the mouse/touch/gestures events:+ PollMouseEvents();+}++//----------------------------------------------------------------------------------+// Module Internal Functions Definition+//----------------------------------------------------------------------------------++// Initialize platform: graphics, inputs and more+int InitPlatform(void)+{+ platform.fd = -1;+ platform.connector = NULL;+ platform.modeIndex = -1;+ platform.crtc = NULL;+ platform.gbmDevice = NULL;+ platform.gbmSurface = NULL;+ platform.prevBO = NULL;+ platform.prevFB = 0;++ // Initialize graphic device: display/window and graphic context+ //----------------------------------------------------------------------------+ CORE.Window.fullscreen = true;+ CORE.Window.flags |= FLAG_FULLSCREEN_MODE;++#if defined(DEFAULT_GRAPHIC_DEVICE_DRM)+ platform.fd = open(DEFAULT_GRAPHIC_DEVICE_DRM, O_RDWR);+#else+ TRACELOG(LOG_INFO, "DISPLAY: No graphic card set, trying platform-gpu-card");+ platform.fd = open("/dev/dri/by-path/platform-gpu-card", O_RDWR); // VideoCore VI (Raspberry Pi 4)++ if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL))+ {+ TRACELOG(LOG_INFO, "DISPLAY: Failed to open platform-gpu-card, trying card1");+ platform.fd = open("/dev/dri/card1", O_RDWR); // Other Embedded+ }++ if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL))+ {+ TRACELOG(LOG_INFO, "DISPLAY: Failed to open graphic card1, trying card0");+ platform.fd = open("/dev/dri/card0", O_RDWR); // VideoCore IV (Raspberry Pi 1-3)+ }+#endif++ if (platform.fd == -1)+ {+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card");+ return -1;+ }++ drmModeRes *res = drmModeGetResources(platform.fd);+ if (!res)+ {+ TRACELOG(LOG_WARNING, "DISPLAY: Failed get DRM resources");+ return -1;+ }++ TRACELOG(LOG_TRACE, "DISPLAY: Connectors found: %i", res->count_connectors);++ for (size_t i = 0; i < res->count_connectors; i++)+ {+ TRACELOG(LOG_TRACE, "DISPLAY: Connector index %i", i);++ drmModeConnector *con = drmModeGetConnector(platform.fd, res->connectors[i]);+ TRACELOG(LOG_TRACE, "DISPLAY: Connector modes detected: %i", con->count_modes);++ if ((con->connection == DRM_MODE_CONNECTED) && (con->encoder_id))+ {+ TRACELOG(LOG_TRACE, "DISPLAY: DRM mode connected");+ platform.connector = con;+ break;+ }+ else+ {+ TRACELOG(LOG_TRACE, "DISPLAY: DRM mode NOT connected (deleting)");+ drmModeFreeConnector(con);+ }+ }++ if (!platform.connector)+ {+ TRACELOG(LOG_WARNING, "DISPLAY: No suitable DRM connector found");+ drmModeFreeResources(res);+ return -1;+ }++ drmModeEncoder *enc = drmModeGetEncoder(platform.fd, platform.connector->encoder_id);+ if (!enc)+ {+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode encoder");+ drmModeFreeResources(res);+ return -1;+ }++ platform.crtc = drmModeGetCrtc(platform.fd, enc->crtc_id);+ if (!platform.crtc)+ {+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode crtc");+ drmModeFreeEncoder(enc);+ drmModeFreeResources(res);+ return -1;+ }++ // If InitWindow should use the current mode find it in the connector's mode list+ if ((CORE.Window.screen.width <= 0) || (CORE.Window.screen.height <= 0))+ {+ TRACELOG(LOG_TRACE, "DISPLAY: Selecting DRM connector mode for current used mode...");++ platform.modeIndex = FindMatchingConnectorMode(platform.connector, &platform.crtc->mode);++ if (platform.modeIndex < 0)+ {+ TRACELOG(LOG_WARNING, "DISPLAY: No matching DRM connector mode found");+ drmModeFreeEncoder(enc);+ drmModeFreeResources(res);+ return -1;+ }++ CORE.Window.screen.width = CORE.Window.display.width;+ CORE.Window.screen.height = CORE.Window.display.height;+ }++ const bool allowInterlaced = CORE.Window.flags & FLAG_INTERLACED_HINT;+ const int fps = (CORE.Time.target > 0)? (1.0/CORE.Time.target) : 60;++ // Try to find an exact matching mode+ platform.modeIndex = FindExactConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);++ // If nothing found, try to find a nearly matching mode+ if (platform.modeIndex < 0) platform.modeIndex = FindNearestConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);++ // If nothing found, try to find an exactly matching mode including interlaced+ if (platform.modeIndex < 0) platform.modeIndex = FindExactConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true);++ // If nothing found, try to find a nearly matching mode including interlaced+ if (platform.modeIndex < 0) platform.modeIndex = FindNearestConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true);++ // If nothing found, there is no suitable mode+ if (platform.modeIndex < 0)+ {+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable DRM connector mode");+ drmModeFreeEncoder(enc);+ drmModeFreeResources(res);+ return -1;+ }++ CORE.Window.display.width = platform.connector->modes[platform.modeIndex].hdisplay;+ CORE.Window.display.height = platform.connector->modes[platform.modeIndex].vdisplay;++ TRACELOG(LOG_INFO, "DISPLAY: Selected DRM connector mode %s (%ux%u%c@%u)", platform.connector->modes[platform.modeIndex].name,+ platform.connector->modes[platform.modeIndex].hdisplay, platform.connector->modes[platform.modeIndex].vdisplay,+ (platform.connector->modes[platform.modeIndex].flags & DRM_MODE_FLAG_INTERLACE)? 'i' : 'p',+ platform.connector->modes[platform.modeIndex].vrefresh);++ // Use the width and height of the surface for render+ CORE.Window.render.width = CORE.Window.screen.width;+ CORE.Window.render.height = CORE.Window.screen.height;++ drmModeFreeEncoder(enc);+ enc = NULL;++ drmModeFreeResources(res);+ res = NULL;++ platform.gbmDevice = gbm_create_device(platform.fd);+ if (!platform.gbmDevice)+ {+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM device");+ return -1;+ }++ platform.gbmSurface = gbm_surface_create(platform.gbmDevice, platform.connector->modes[platform.modeIndex].hdisplay,+ platform.connector->modes[platform.modeIndex].vdisplay, GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);+ if (!platform.gbmSurface)+ {+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM surface");+ return -1;+ }++ EGLint samples = 0;+ EGLint sampleBuffer = 0;+ if (CORE.Window.flags & FLAG_MSAA_4X_HINT)+ {+ samples = 4;+ sampleBuffer = 1;+ TRACELOG(LOG_INFO, "DISPLAY: Trying to enable MSAA x4");+ }++ const EGLint framebufferAttribs[] =+ {+ EGL_RENDERABLE_TYPE, (rlGetVersion() == RL_OPENGL_ES_30)? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT, // Type of context support+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT, // Don't use it on Android!+ EGL_RED_SIZE, 8, // RED color bit depth (alternative: 5)+ EGL_GREEN_SIZE, 8, // GREEN color bit depth (alternative: 6)+ EGL_BLUE_SIZE, 8, // BLUE color bit depth (alternative: 5)+ EGL_ALPHA_SIZE, 8, // ALPHA bit depth (required for transparent framebuffer)+ //EGL_TRANSPARENT_TYPE, EGL_NONE, // Request transparent framebuffer (EGL_TRANSPARENT_RGB does not work on RPI)+ EGL_DEPTH_SIZE, 16, // Depth buffer size (Required to use Depth testing!)+ //EGL_STENCIL_SIZE, 8, // Stencil buffer size+ EGL_SAMPLE_BUFFERS, sampleBuffer, // Activate MSAA+ EGL_SAMPLES, samples, // 4x Antialiasing if activated (Free on MALI GPUs)+ EGL_NONE+ };++ const EGLint contextAttribs[] = {+ EGL_CONTEXT_CLIENT_VERSION, 2,+ EGL_NONE+ };++ EGLint numConfigs = 0;++ // Get an EGL device connection+ platform.device = eglGetDisplay((EGLNativeDisplayType)platform.gbmDevice);+ if (platform.device == EGL_NO_DISPLAY)+ {+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");+ return -1;+ }++ // Initialize the EGL device connection+ if (eglInitialize(platform.device, NULL, NULL) == EGL_FALSE)+ {+ // If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");+ return -1;+ }++ if (!eglChooseConfig(platform.device, NULL, NULL, 0, &numConfigs))+ {+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to get EGL config count: 0x%x", eglGetError());+ return -1;+ }++ TRACELOG(LOG_TRACE, "DISPLAY: EGL configs available: %d", numConfigs);++ EGLConfig *configs = RL_CALLOC(numConfigs, sizeof(*configs));+ if (!configs)+ {+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to get memory for EGL configs");+ return -1;+ }++ EGLint matchingNumConfigs = 0;+ if (!eglChooseConfig(platform.device, framebufferAttribs, configs, numConfigs, &matchingNumConfigs))+ {+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to choose EGL config: 0x%x", eglGetError());+ free(configs);+ return -1;+ }++ TRACELOG(LOG_TRACE, "DISPLAY: EGL matching configs available: %d", matchingNumConfigs);++ // find the EGL config that matches the previously setup GBM format+ int found = 0;+ for (EGLint i = 0; i < matchingNumConfigs; ++i)+ {+ EGLint id = 0;+ if (!eglGetConfigAttrib(platform.device, configs[i], EGL_NATIVE_VISUAL_ID, &id))+ {+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to get EGL config attribute: 0x%x", eglGetError());+ continue;+ }++ if (GBM_FORMAT_ARGB8888 == id)+ {+ TRACELOG(LOG_TRACE, "DISPLAY: Using EGL config: %d", i);+ platform.config = configs[i];+ found = 1;+ break;+ }+ }++ RL_FREE(configs);++ if (!found)+ {+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable EGL config");+ return -1;+ }++ // Set rendering API+ eglBindAPI(EGL_OPENGL_ES_API);++ // Create an EGL rendering context+ platform.context = eglCreateContext(platform.device, platform.config, EGL_NO_CONTEXT, contextAttribs);+ if (platform.context == EGL_NO_CONTEXT)+ {+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");+ return -1;+ }++ // Create an EGL window surface+ platform.surface = eglCreateWindowSurface(platform.device, platform.config, (EGLNativeWindowType)platform.gbmSurface, NULL);+ if (EGL_NO_SURFACE == platform.surface)+ {+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL window surface: 0x%04x", eglGetError());+ return -1;+ }++ // At this point we need to manage render size vs screen size+ // NOTE: This function use and modify global module variables:+ // -> CORE.Window.screen.width/CORE.Window.screen.height+ // -> CORE.Window.render.width/CORE.Window.render.height+ // -> CORE.Window.screenScale+ SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);++ // There must be at least one frame displayed before the buffers are swapped+ //eglSwapInterval(platform.device, 1);++ EGLBoolean result = eglMakeCurrent(platform.device, platform.surface, platform.surface, platform.context);++ // Check surface and context activation+ if (result != EGL_FALSE)+ {+ CORE.Window.ready = true;++ CORE.Window.render.width = CORE.Window.screen.width;+ CORE.Window.render.height = CORE.Window.screen.height;+ CORE.Window.currentFbo.width = CORE.Window.render.width;+ CORE.Window.currentFbo.height = CORE.Window.render.height;++ TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully");+ TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height);+ TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height);+ TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);+ TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);+ }+ else+ {+ TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphics device");+ return -1;+ }++ if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();++ // If graphic device is no properly initialized, we end program+ if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; }+ else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor()) / 2 - CORE.Window.screen.width / 2, GetMonitorHeight(GetCurrentMonitor()) / 2 - CORE.Window.screen.height / 2);++ // Set some default window flags+ CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false+ CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false+ CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true+ CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false++ // Load OpenGL extensions+ // NOTE: GL procedures address loader is required to load extensions+ rlLoadExtensions(eglGetProcAddress);+ //----------------------------------------------------------------------------++ // Initialize timming system+ //----------------------------------------------------------------------------+ // NOTE: timming system must be initialized before the input events system+ InitTimer();+ //----------------------------------------------------------------------------++ // Initialize input events system+ //----------------------------------------------------------------------------+ InitEvdevInput(); // Evdev inputs initialization++#if defined(SUPPORT_SSH_KEYBOARD_RPI)+ InitKeyboard(); // Keyboard init (stdin)+#endif+ //----------------------------------------------------------------------------++ // Initialize storage system+ //----------------------------------------------------------------------------+ CORE.Storage.basePath = GetWorkingDirectory();+ //----------------------------------------------------------------------------++ TRACELOG(LOG_INFO, "PLATFORM: DRM: Initialized successfully");++ return 0;+}++// Close platform+void ClosePlatform(void)+{+ if (platform.prevFB)+ {+ drmModeRmFB(platform.fd, platform.prevFB);+ platform.prevFB = 0;+ }++ if (platform.prevBO)+ {+ gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);+ platform.prevBO = NULL;+ }++ if (platform.gbmSurface)+ {+ gbm_surface_destroy(platform.gbmSurface);+ platform.gbmSurface = NULL;+ }++ if (platform.gbmDevice)+ {+ gbm_device_destroy(platform.gbmDevice);+ platform.gbmDevice = NULL;+ }++ if (platform.crtc)+ {+ if (platform.connector)+ {+ drmModeSetCrtc(platform.fd, platform.crtc->crtc_id, platform.crtc->buffer_id,+ platform.crtc->x, platform.crtc->y, &platform.connector->connector_id, 1, &platform.crtc->mode);+ drmModeFreeConnector(platform.connector);+ platform.connector = NULL;+ }++ drmModeFreeCrtc(platform.crtc);+ platform.crtc = NULL;+ }++ if (platform.fd != -1)+ {+ close(platform.fd);+ platform.fd = -1;+ }++ // Close surface, context and display+ if (platform.device != EGL_NO_DISPLAY)+ {+ if (platform.surface != EGL_NO_SURFACE)+ {+ eglDestroySurface(platform.device, platform.surface);+ platform.surface = EGL_NO_SURFACE;+ }++ if (platform.context != EGL_NO_CONTEXT)+ {+ eglDestroyContext(platform.device, platform.context);+ platform.context = EGL_NO_CONTEXT;+ }++ eglTerminate(platform.device);+ platform.device = EGL_NO_DISPLAY;+ }++ CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called++ // Close the evdev devices++ if (platform.mouseFd != -1) {+ close(platform.mouseFd);+ platform.mouseFd = -1;+ }++ for (int i = 0; i < platform.gamepadCount; i++)+ {+ close(platform.gamepadStreamFd[i]);+ platform.gamepadStreamFd[i] = -1;+ }++ if (platform.keyboardFd != -1)+ {+ close(platform.keyboardFd);+ platform.keyboardFd = -1;+ }+}++#if defined(SUPPORT_SSH_KEYBOARD_RPI)+// Initialize Keyboard system (using standard input)+static void InitKeyboard(void)+{+ // NOTE: We read directly from Standard Input (stdin) - STDIN_FILENO file descriptor,+ // Reading directly from stdin will give chars already key-mapped by kernel to ASCII or UNICODE++ // Save terminal keyboard settings+ tcgetattr(STDIN_FILENO, &platform.defaultSettings);++ // Reconfigure terminal with new settings+ struct termios keyboardNewSettings = { 0 };+ keyboardNewSettings = platform.defaultSettings;++ // New terminal settings for keyboard: turn off buffering (non-canonical mode), echo and key processing+ // NOTE: ISIG controls if ^C and ^Z generate break signals or not+ keyboardNewSettings.c_lflag &= ~(ICANON | ECHO | ISIG);+ //keyboardNewSettings.c_iflag &= ~(ISTRIP | INLCR | ICRNL | IGNCR | IXON | IXOFF);+ keyboardNewSettings.c_cc[VMIN] = 1;+ keyboardNewSettings.c_cc[VTIME] = 0;++ // Set new keyboard settings (change occurs immediately)+ tcsetattr(STDIN_FILENO, TCSANOW, &keyboardNewSettings);++ // Save old keyboard mode to restore it at the end+ platform.defaultFileFlags = fcntl(STDIN_FILENO, F_GETFL, 0); // F_GETFL: Get the file access mode and the file status flags+ fcntl(STDIN_FILENO, F_SETFL, platform.defaultFileFlags | O_NONBLOCK); // F_SETFL: Set the file status flags to the value specified++ // NOTE: If ioctl() returns -1, it means the call failed for some reason (error code set in errno)+ int result = ioctl(STDIN_FILENO, KDGKBMODE, &platform.defaultKeyboardMode);++ // In case of failure, it could mean a remote keyboard is used (SSH)+ if (result < 0) TRACELOG(LOG_WARNING, "DRM: Failed to change keyboard mode, an SSH keyboard is probably used");+ else+ {+ // Reconfigure keyboard mode to get:+ // - scancodes (K_RAW)+ // - keycodes (K_MEDIUMRAW)+ // - ASCII chars (K_XLATE)+ // - UNICODE chars (K_UNICODE)+ ioctl(STDIN_FILENO, KDSKBMODE, K_XLATE); // ASCII chars+ }++ // Register keyboard restore when program finishes+ atexit(RestoreKeyboard);+}++// Restore default keyboard input+static void RestoreKeyboard(void)+{+ // Reset to default keyboard settings+ tcsetattr(STDIN_FILENO, TCSANOW, &platform.defaultSettings);++ // Reconfigure keyboard to default mode+ fcntl(STDIN_FILENO, F_SETFL, platform.defaultFileFlags);+ ioctl(STDIN_FILENO, KDSKBMODE, platform.defaultKeyboardMode);+}++// Process keyboard inputs+static void ProcessKeyboard(void)+{+ #define MAX_KEYBUFFER_SIZE 32 // Max size in bytes to read++ // Keyboard input polling (fill keys[256] array with status)+ int bufferByteCount = 0; // Bytes available on the buffer+ char keysBuffer[MAX_KEYBUFFER_SIZE] = { 0 }; // Max keys to be read at a time++ // Read availables keycodes from stdin+ bufferByteCount = read(STDIN_FILENO, keysBuffer, MAX_KEYBUFFER_SIZE); // POSIX system call++ // Reset pressed keys array (it will be filled below)+ for (int i = 0; i < MAX_KEYBOARD_KEYS; i++)+ {+ CORE.Input.Keyboard.currentKeyState[i] = 0;+ CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;+ }++ // Fill all read bytes (looking for keys)+ for (int i = 0; i < bufferByteCount; i++)+ {+ // NOTE: If (key == 0x1b), depending on next key, it could be a special keymap code!+ // Up -> 1b 5b 41 / Left -> 1b 5b 44 / Right -> 1b 5b 43 / Down -> 1b 5b 42+ if (keysBuffer[i] == 0x1b)+ {+ // Check if ESCAPE key has been pressed to stop program+ if (bufferByteCount == 1) CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] = 1;+ else+ {+ if (keysBuffer[i + 1] == 0x5b) // Special function key+ {+ if ((keysBuffer[i + 2] == 0x5b) || (keysBuffer[i + 2] == 0x31) || (keysBuffer[i + 2] == 0x32))+ {+ // Process special function keys (F1 - F12)+ switch (keysBuffer[i + 3])+ {+ case 0x41: CORE.Input.Keyboard.currentKeyState[290] = 1; break; // raylib KEY_F1+ case 0x42: CORE.Input.Keyboard.currentKeyState[291] = 1; break; // raylib KEY_F2+ case 0x43: CORE.Input.Keyboard.currentKeyState[292] = 1; break; // raylib KEY_F3+ case 0x44: CORE.Input.Keyboard.currentKeyState[293] = 1; break; // raylib KEY_F4+ case 0x45: CORE.Input.Keyboard.currentKeyState[294] = 1; break; // raylib KEY_F5+ case 0x37: CORE.Input.Keyboard.currentKeyState[295] = 1; break; // raylib KEY_F6+ case 0x38: CORE.Input.Keyboard.currentKeyState[296] = 1; break; // raylib KEY_F7+ case 0x39: CORE.Input.Keyboard.currentKeyState[297] = 1; break; // raylib KEY_F8+ case 0x30: CORE.Input.Keyboard.currentKeyState[298] = 1; break; // raylib KEY_F9+ case 0x31: CORE.Input.Keyboard.currentKeyState[299] = 1; break; // raylib KEY_F10+ case 0x33: CORE.Input.Keyboard.currentKeyState[300] = 1; break; // raylib KEY_F11+ case 0x34: CORE.Input.Keyboard.currentKeyState[301] = 1; break; // raylib KEY_F12+ default: break;+ }++ if (keysBuffer[i + 2] == 0x5b) i += 4;+ else if ((keysBuffer[i + 2] == 0x31) || (keysBuffer[i + 2] == 0x32)) i += 5;+ }+ else+ {+ switch (keysBuffer[i + 2])+ {+ case 0x41: CORE.Input.Keyboard.currentKeyState[265] = 1; break; // raylib KEY_UP+ case 0x42: CORE.Input.Keyboard.currentKeyState[264] = 1; break; // raylib KEY_DOWN+ case 0x43: CORE.Input.Keyboard.currentKeyState[262] = 1; break; // raylib KEY_RIGHT+ case 0x44: CORE.Input.Keyboard.currentKeyState[263] = 1; break; // raylib KEY_LEFT+ default: break;+ }++ i += 3; // Jump to next key+ }++ // NOTE: Some keys are not directly keymapped (CTRL, ALT, SHIFT)+ }+ }+ }+ else if (keysBuffer[i] == 0x0a) // raylib KEY_ENTER (don't mix with <linux/input.h> KEY_*)+ {+ CORE.Input.Keyboard.currentKeyState[257] = 1;++ CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = 257; // Add keys pressed into queue+ CORE.Input.Keyboard.keyPressedQueueCount++;+ }+ else if (keysBuffer[i] == 0x7f) // raylib KEY_BACKSPACE+ {+ CORE.Input.Keyboard.currentKeyState[259] = 1;++ CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = 257; // Add keys pressed into queue+ CORE.Input.Keyboard.keyPressedQueueCount++;+ }+ else+ {+ // Translate lowercase a-z letters to A-Z+ if ((keysBuffer[i] >= 97) && (keysBuffer[i] <= 122))+ {+ CORE.Input.Keyboard.currentKeyState[(int)keysBuffer[i] - 32] = 1;+ }+ else CORE.Input.Keyboard.currentKeyState[(int)keysBuffer[i]] = 1;++ CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keysBuffer[i]; // Add keys pressed into queue+ CORE.Input.Keyboard.keyPressedQueueCount++;+ }+ }+}+#endif // SUPPORT_SSH_KEYBOARD_RPI++// Initialise user input from evdev(/dev/input/event<N>)+// this means mouse, keyboard or gamepad devices+static void InitEvdevInput(void)+{+ char path[MAX_FILEPATH_LENGTH] = { 0 };+ DIR *directory = NULL;+ struct dirent *entity = NULL;++ // Initialise keyboard file descriptor+ platform.keyboardFd = -1;+ platform.mouseFd = -1;++ // Reset variables+ for (int i = 0; i < MAX_TOUCH_POINTS; ++i)+ {+ CORE.Input.Touch.position[i].x = -1;+ CORE.Input.Touch.position[i].y = -1;+ }++ // Reset keyboard key state+ for (int i = 0; i < MAX_KEYBOARD_KEYS; i++)+ {+ CORE.Input.Keyboard.currentKeyState[i] = 0;+ CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;+ }++ // Open the linux directory of "/dev/input"+ directory = opendir(DEFAULT_EVDEV_PATH);++ if (directory)+ {+ while ((entity = readdir(directory)) != NULL)+ {+ if ((strncmp("event", entity->d_name, strlen("event")) == 0) || // Search for devices named "event*"+ (strncmp("mouse", entity->d_name, strlen("mouse")) == 0)) // Search for devices named "mouse*"+ {+ sprintf(path, "%s%s", DEFAULT_EVDEV_PATH, entity->d_name);+ ConfigureEvdevDevice(path); // Configure the device if appropriate+ }+ }++ closedir(directory);+ }+ else TRACELOG(LOG_WARNING, "INPUT: Failed to open linux event directory: %s", DEFAULT_EVDEV_PATH);+}++// Identifies a input device and configures it for use if appropriate+static void ConfigureEvdevDevice(char *device)+{+ #define BITS_PER_LONG (8*sizeof(long))+ #define NBITS(x) ((((x) - 1)/BITS_PER_LONG) + 1)+ #define OFF(x) ((x)%BITS_PER_LONG)+ #define BIT(x) (1UL<<OFF(x))+ #define LONG(x) ((x)/BITS_PER_LONG)+ #define TEST_BIT(array, bit) ((array[LONG(bit)] >> OFF(bit)) & 1)++ unsigned long evBits[NBITS(EV_MAX)] = { 0 };+ unsigned long absBits[NBITS(ABS_MAX)] = { 0 };+ unsigned long relBits[NBITS(REL_MAX)] = { 0 };+ unsigned long keyBits[NBITS(KEY_MAX)] = { 0 };++ // Open the device+ int fd = open(device, O_RDONLY | O_NONBLOCK);+ if (fd < 0)+ {+ TRACELOG(LOG_WARNING, "DRM: Failed to open input device: %s", device);+ return;+ }++ // At this point we have a connection to the device, but we don't yet know what the device is.+ // It could be many things, even as simple as a power button...+ //-------------------------------------------------------------------------------------------------------++ // Identify the device+ //-------------------------------------------------------------------------------------------------------+ struct {+ bool exist;+ struct input_absinfo info;+ } absinfo[ABS_CNT] = { 0 };++ // These flags aren't really a one of+ // Some devices could have properties we assosciate with keyboards as well as properties+ // we assosciate with mice+ bool isKeyboard = false;+ bool isMouse = false;+ bool isTouch = false;+ bool isGamepad = false;++ int absAxisCount = 0;++ ioctl(fd, EVIOCGBIT(0, sizeof(evBits)), evBits);+ ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits);++ if (TEST_BIT(evBits, EV_ABS))+ {+ ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits);++ // If the device has an X an Y axis it's either a touch device, a special mouse or a gamepad+ bool hasAbsXY = TEST_BIT(absBits, ABS_X) && TEST_BIT(absBits, ABS_Y);++ if (hasAbsXY)+ {+ absAxisCount += 2;++ absinfo[ABS_X].exist = true;+ absinfo[ABS_Y].exist = true;++ ioctl(fd, EVIOCGABS(ABS_X), &absinfo[ABS_X].info);+ ioctl(fd, EVIOCGABS(ABS_Y), &absinfo[ABS_Y].info);+ }++ // If it has any of these buttons it's a touch device+ if (hasAbsXY &&+ (TEST_BIT(keyBits, BTN_STYLUS) ||+ TEST_BIT(keyBits, BTN_TOOL_PEN) ||+ TEST_BIT(keyBits, BTN_TOOL_FINGER) ||+ TEST_BIT(keyBits, BTN_TOUCH))) isTouch = true;++ // Absolute mice should really only exist with VMWare, but it shouldn't+ // matter if we support them+ else if (hasAbsXY && TEST_BIT(keyBits, BTN_MOUSE)) isMouse = true;++ // If any of the common joystick axis is present, we assume it's a gamepad+ else+ {+ for (int axis = (hasAbsXY? ABS_Z : ABS_X); axis < ABS_PRESSURE; axis++)+ {+ if (TEST_BIT(absBits, axis))+ {+ absinfo[axis].exist = true;+ isGamepad = true;+ absAxisCount++;++ ioctl(fd, EVIOCGABS(axis), &absinfo[axis].info);+ }+ }+ }++ // If the device has multitouch axes, it's a touch device+ if (TEST_BIT(absBits, ABS_MT_POSITION_X) &&+ TEST_BIT(absBits, ABS_MT_POSITION_Y)) isTouch = true;+ }++ if (TEST_BIT(evBits, EV_REL))+ {+ ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relBits)), relBits);++ // If it has any of the gamepad or touch features we tested so far, it's not a mouse+ if (!isTouch &&+ !isGamepad &&+ TEST_BIT(relBits, REL_X) &&+ TEST_BIT(relBits, REL_Y) &&+ TEST_BIT(keyBits, BTN_MOUSE)) isMouse = true;+ }+++ if (TEST_BIT(evBits, EV_KEY))+ {+ // The first 32 keys as defined in input-event-codes.h are pretty much+ // exclusive to keyboards, so we can test them using a mask+ // Leave out the first bit to not test KEY_RESERVED+ const unsigned long mask = 0xFFFFFFFE;+ if ((keyBits[0] & mask) == mask) isKeyboard = true;++ // If we find any of the common gamepad buttons we assume it's a gamepad+ else+ {+ for (int button = BTN_JOYSTICK; button < BTN_DIGI; ++button)+ {+ if (TEST_BIT(keyBits, button)) isGamepad = true;+ }++ for (int button = BTN_TRIGGER_HAPPY1; button <= BTN_TRIGGER_HAPPY40; button++)+ {+ if (TEST_BIT(keyBits, button)) isGamepad = true;+ }+ }+ }++ const char *deviceKindStr = "unknown";+ if (isMouse || isTouch)+ {+ deviceKindStr = "mouse";+ if (platform.mouseFd != -1) close(platform.mouseFd);+ platform.mouseFd = fd;++ if (absAxisCount > 0)+ {+ platform.absRange.x = absinfo[ABS_X].info.minimum;+ platform.absRange.width = absinfo[ABS_X].info.maximum - absinfo[ABS_X].info.minimum;++ platform.absRange.y = absinfo[ABS_Y].info.minimum;+ platform.absRange.height = absinfo[ABS_Y].info.maximum - absinfo[ABS_Y].info.minimum;+ }+ }+ else if (isGamepad && !isMouse && !isKeyboard && platform.gamepadCount < MAX_GAMEPADS)+ {+ deviceKindStr = "gamepad";+ int index = platform.gamepadCount++;++ platform.gamepadStreamFd[index] = fd;+ CORE.Input.Gamepad.ready[index] = true;++ ioctl(platform.gamepadStreamFd[index], EVIOCGNAME(64), &CORE.Input.Gamepad.name[index]);+ CORE.Input.Gamepad.axisCount[index] = absAxisCount;++ if (absAxisCount > 0)+ {+ // TODO / NOTE+ // So gamepad axis (as in the actual linux joydev.c) are just simply enumerated+ // and (at least for some input drivers like xpat) it's convention to use+ // ABS_X, ABX_Y for one joystick ABS_RX, ABS_RY for the other and the Z axes for the+ // shoulder buttons+ // If these are now enumerated you get LJOY_X, LJOY_Y, LEFT_SHOULDERB, RJOY_X, ...+ // That means they don't match the GamepadAxis enum+ // This could be fixed+ int axisIndex = 0;+ for (int axis = ABS_X; axis < ABS_PRESSURE; axis++)+ {+ if (absinfo[axis].exist)+ {+ platform.gamepadAbsAxisRange[index][axisIndex][0] = absinfo[axisIndex].info.minimum;+ platform.gamepadAbsAxisRange[index][axisIndex][1] = absinfo[axisIndex].info.maximum - absinfo[axisIndex].info.minimum;++ platform.gamepadAbsAxisMap[index][axis] = axisIndex;+ axisIndex++;+ }+ }+ }+ }+ else if (isKeyboard && (platform.keyboardFd == -1))+ {+ deviceKindStr = "keyboard";+ platform.keyboardFd = fd;+ }+ else+ {+ close(fd);+ return;+ }++ TRACELOG(LOG_INFO, "INPUT: Initialized input device %s as %s", device, deviceKindStr);+}++// Poll and process evdev keyboard events+static void PollKeyboardEvents(void)+{+ int fd = platform.keyboardFd;+ if (fd == -1) return;++ struct input_event event = { 0 };+ int keycode = -1;++ // Try to read data from the keyboard and only continue if successful+ while (read(fd, &event, sizeof(event)) == (int)sizeof(event))+ {+ // Check if the event is a key event+ if (event.type != EV_KEY) continue;++#if defined(SUPPORT_SSH_KEYBOARD_RPI)+ // If the event was a key, we know a working keyboard is connected, so disable the SSH keyboard+ platform.eventKeyboardMode = true;+#endif++ // Keyboard keys appear for codes 1 to 255, ignore everthing else+ if ((event.code >= 1) && (event.code <= 255))+ {++ // Lookup the scancode in the keymap to get a keycode+ keycode = linuxToRaylibMap[event.code];++ // Make sure we got a valid keycode+ if ((keycode > 0) && (keycode < MAX_KEYBOARD_KEYS))+ {++ // WARNING: https://www.kernel.org/doc/Documentation/input/input.txt+ // Event interface: 'value' is the value the event carries. Either a relative change for EV_REL,+ // absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat+ CORE.Input.Keyboard.currentKeyState[keycode] = (event.value >= 1);+ CORE.Input.Keyboard.keyRepeatInFrame[keycode] = (event.value == 2);++ // If the key is pressed add it to the queues+ if (event.value == 1)+ {+ if (CORE.Input.Keyboard.keyPressedQueueCount < MAX_CHAR_PRESSED_QUEUE)+ {+ CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode;+ CORE.Input.Keyboard.keyPressedQueueCount++;+ }++ if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE)+ {+ // TODO/FIXME: This is not actually converting to unicode properly because it's not taking things like shift into account+ CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = evkeyToUnicodeLUT[event.code];+ CORE.Input.Keyboard.charPressedQueueCount++;+ }+ }++ TRACELOG(LOG_DEBUG, "INPUT: KEY_%s Keycode(linux): %4i KeyCode(raylib): %4i", (event.value == 0) ? "UP " : "DOWN", event.code, keycode);+ }+ }+ }+}++// Poll gamepad input events+static void PollGamepadEvents(void)+{+ // Read gamepad event+ struct input_event event = { 0 };++ for (int i = 0; i < platform.gamepadCount; i++)+ {+ if (!CORE.Input.Gamepad.ready[i]) continue;++ // Register previous gamepad states+ for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k];++ while (read(platform.gamepadStreamFd[i], &event, sizeof(event)) == (int)sizeof(event))+ {+ if (event.type == EV_KEY)+ {+ if (event.code < KEYMAP_SIZE)+ {+ short keycodeRaylib = linuxToRaylibMap[event.code];++ TRACELOG(LOG_DEBUG, "INPUT: Gamepad %2i: KEY_%s Keycode(linux): %4i Keycode(raylib): %4i", i, (event.value == 0) ? "UP " : "DOWN", event.code, keycodeRaylib);++ if ((keycodeRaylib != 0) && (keycodeRaylib < MAX_GAMEPAD_BUTTONS))+ {+ // 1 - button pressed, 0 - button released+ CORE.Input.Gamepad.currentButtonState[i][keycodeRaylib] = event.value;++ CORE.Input.Gamepad.lastButtonPressed = (event.value == 1)? keycodeRaylib : GAMEPAD_BUTTON_UNKNOWN;+ }+ }+ }+ else if (event.type == EV_ABS)+ {+ if (event.code < ABS_CNT)+ {+ int axisRaylib = platform.gamepadAbsAxisMap[i][event.code];++ TRACELOG(LOG_DEBUG, "INPUT: Gamepad %2i: Axis: %2i Value: %i", i, axisRaylib, event.value);++ if (axisRaylib < MAX_GAMEPAD_AXIS)+ {+ int min = platform.gamepadAbsAxisRange[i][event.code][0];+ int range = platform.gamepadAbsAxisRange[i][event.code][1];++ // NOTE: Scaling of event.value to get values between -1..1+ CORE.Input.Gamepad.axisState[i][axisRaylib] = (2 * (float)(event.value - min) / range) - 1;+ }+ }+ }+ }+ }+}++// Poll mouse input events+static void PollMouseEvents(void)+{+ int fd = platform.mouseFd;+ if (fd == -1) return;++ struct input_event event = { 0 };+ int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE++ // Try to read data from the mouse/touch/gesture and only continue if successful+ while (read(fd, &event, sizeof(event)) == (int)sizeof(event))+ {+ // Relative movement parsing+ if (event.type == EV_REL)+ {+ if (event.code == REL_X)+ {+ if (platform.cursorRelative)+ {+ CORE.Input.Mouse.currentPosition.x = event.value;+ CORE.Input.Mouse.previousPosition.x = 0.0f;+ }+ else CORE.Input.Mouse.currentPosition.x += event.value;++ CORE.Input.Touch.position[0].x = CORE.Input.Mouse.currentPosition.x;+ touchAction = 2; // TOUCH_ACTION_MOVE+ }++ if (event.code == REL_Y)+ {+ if (platform.cursorRelative)+ {+ CORE.Input.Mouse.currentPosition.y = event.value;+ CORE.Input.Mouse.previousPosition.y = 0.0f;+ }+ else CORE.Input.Mouse.currentPosition.y += event.value;++ CORE.Input.Touch.position[0].y = CORE.Input.Mouse.currentPosition.y;+ touchAction = 2; // TOUCH_ACTION_MOVE+ }++ if (event.code == REL_WHEEL) platform.eventWheelMove.y += event.value;+ }++ // Absolute movement parsing+ if (event.type == EV_ABS)+ {+ // Basic movement+ if (event.code == ABS_X)+ {+ CORE.Input.Mouse.currentPosition.x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange+ CORE.Input.Touch.position[0].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange++ touchAction = 2; // TOUCH_ACTION_MOVE+ }++ if (event.code == ABS_Y)+ {+ CORE.Input.Mouse.currentPosition.y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange+ CORE.Input.Touch.position[0].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange++ touchAction = 2; // TOUCH_ACTION_MOVE+ }++ // Multitouch movement+ if (event.code == ABS_MT_SLOT) platform.touchSlot = event.value; // Remember the slot number for the folowing events++ if (event.code == ABS_MT_POSITION_X)+ {+ if (platform.touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[platform.touchSlot].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange+ }++ if (event.code == ABS_MT_POSITION_Y)+ {+ if (platform.touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[platform.touchSlot].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange+ }++ if (event.code == ABS_MT_TRACKING_ID)+ {+ if ((event.value < 0) && (platform.touchSlot < MAX_TOUCH_POINTS))+ {+ // Touch has ended for this point+ CORE.Input.Touch.position[platform.touchSlot].x = -1;+ CORE.Input.Touch.position[platform.touchSlot].y = -1;+ }+ }++ // Touchscreen tap+ if (event.code == ABS_PRESSURE)+ {+ int previousMouseLeftButtonState = platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT];++ if (!event.value && previousMouseLeftButtonState)+ {+ platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0;+ touchAction = 0; // TOUCH_ACTION_UP+ }++ if (event.value && !previousMouseLeftButtonState)+ {+ platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 1;+ touchAction = 1; // TOUCH_ACTION_DOWN+ }+ }++ }++ // Button parsing+ if (event.type == EV_KEY)+ {+ // Mouse button parsing+ if ((event.code == BTN_TOUCH) || (event.code == BTN_LEFT))+ {+ platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = event.value;++ if (event.value > 0) touchAction = 1; // TOUCH_ACTION_DOWN+ else touchAction = 0; // TOUCH_ACTION_UP+ }++ if (event.code == BTN_RIGHT) platform.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value;+ if (event.code == BTN_MIDDLE) platform.currentButtonStateEvdev[MOUSE_BUTTON_MIDDLE] = event.value;+ if (event.code == BTN_SIDE) platform.currentButtonStateEvdev[MOUSE_BUTTON_SIDE] = event.value;+ if (event.code == BTN_EXTRA) platform.currentButtonStateEvdev[MOUSE_BUTTON_EXTRA] = event.value;+ if (event.code == BTN_FORWARD) platform.currentButtonStateEvdev[MOUSE_BUTTON_FORWARD] = event.value;+ if (event.code == BTN_BACK) platform.currentButtonStateEvdev[MOUSE_BUTTON_BACK] = event.value;+ }++ // Screen confinement+ if (!CORE.Input.Mouse.cursorHidden)+ {+ if (CORE.Input.Mouse.currentPosition.x < 0) CORE.Input.Mouse.currentPosition.x = 0;+ if (CORE.Input.Mouse.currentPosition.x > CORE.Window.screen.width/CORE.Input.Mouse.scale.x) CORE.Input.Mouse.currentPosition.x = CORE.Window.screen.width/CORE.Input.Mouse.scale.x;++ if (CORE.Input.Mouse.currentPosition.y < 0) CORE.Input.Mouse.currentPosition.y = 0;+ if (CORE.Input.Mouse.currentPosition.y > CORE.Window.screen.height/CORE.Input.Mouse.scale.y) CORE.Input.Mouse.currentPosition.y = CORE.Window.screen.height/CORE.Input.Mouse.scale.y;+ }++ // Update touch point count+ CORE.Input.Touch.pointCount = 0;+ for (int i = 0; i < MAX_TOUCH_POINTS; i++)+ {+ if (CORE.Input.Touch.position[i].x >= 0) CORE.Input.Touch.pointCount++;+ }++#if defined(SUPPORT_GESTURES_SYSTEM)+ if (touchAction > -1)+ {+ GestureEvent gestureEvent = { 0 };++ gestureEvent.touchAction = touchAction;+ gestureEvent.pointCount = CORE.Input.Touch.pointCount;++ for (int i = 0; i < MAX_TOUCH_POINTS; i++)+ {+ gestureEvent.pointId[i] = i;+ gestureEvent.position[i] = CORE.Input.Touch.position[i];+ }++ ProcessGestureEvent(gestureEvent);++ touchAction = -1;+ }+#endif } }
raylib/src/platforms/rcore_web.c view
@@ -850,6 +850,12 @@ return 0; } +// Set gamepad vibration+void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)+{+ TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform");+}+ // Set mouse position XY void SetMousePosition(int x, int y) {
raylib/src/raudio.c view
@@ -942,13 +942,13 @@ if (source.stream.buffer->data != NULL) { AudioBuffer *audioBuffer = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, 0, AUDIO_BUFFER_USAGE_STATIC);- + if (audioBuffer == NULL) { TRACELOG(LOG_WARNING, "SOUND: Failed to create buffer"); return sound; // Early return to avoid dereferencing the audioBuffer null pointer }- + audioBuffer->sizeInFrames = source.stream.buffer->sizeInFrames; audioBuffer->volume = source.stream.buffer->volume; audioBuffer->data = source.stream.buffer->data;@@ -1081,7 +1081,7 @@ int waveDataSize = wave.frameCount*wave.channels*wave.sampleSize/8; // NOTE: Text data buffer size is estimated considering wave data size in bytes- // and requiring 12 char bytes for every byte; the actual size varies, but + // and requiring 12 char bytes for every byte; the actual size varies, but // the longest possible char being appended is "%.4ff,\n ", which is 12 bytes. char *txtData = (char *)RL_CALLOC(waveDataSize*12 + 2000, sizeof(char)); @@ -2752,7 +2752,7 @@ return false; } }- else + else { TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); return false;
raylib/src/raylib.h view
@@ -721,9 +721,9 @@ GAMEPAD_BUTTON_LEFT_FACE_DOWN, // Gamepad left DPAD down button GAMEPAD_BUTTON_LEFT_FACE_LEFT, // Gamepad left DPAD left button GAMEPAD_BUTTON_RIGHT_FACE_UP, // Gamepad right button up (i.e. PS3: Triangle, Xbox: Y)- GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, // Gamepad right button right (i.e. PS3: Square, Xbox: X)+ GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, // Gamepad right button right (i.e. PS3: Circle, Xbox: B) GAMEPAD_BUTTON_RIGHT_FACE_DOWN, // Gamepad right button down (i.e. PS3: Cross, Xbox: A)- GAMEPAD_BUTTON_RIGHT_FACE_LEFT, // Gamepad right button left (i.e. PS3: Circle, Xbox: B)+ GAMEPAD_BUTTON_RIGHT_FACE_LEFT, // Gamepad right button left (i.e. PS3: Square, Xbox: X) GAMEPAD_BUTTON_LEFT_TRIGGER_1, // Gamepad top/back trigger left (first), it could be a trailing button GAMEPAD_BUTTON_LEFT_TRIGGER_2, // Gamepad top/back trigger left (second), it could be a trailing button GAMEPAD_BUTTON_RIGHT_TRIGGER_1, // Gamepad top/back trigger right (one), it could be a trailing button@@ -1049,8 +1049,9 @@ RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM) // Screen-space-related functions-RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Get a ray trace from mouse position-RLAPI Ray GetViewRay(Vector2 mousePosition, Camera camera, float width, float height); // Get a ray trace from mouse position in a viewport+#define GetMouseRay GetScreenToWorldRay // Compatibility hack for previous raylib versions+RLAPI Ray GetScreenToWorldRay(Vector2 position, Camera camera); // Get a ray trace from screen position (i.e mouse)+RLAPI Ray GetScreenToWorldRayEx(Vector2 position, Camera camera, int width, int height); // Get a ray trace from screen position (i.e mouse) in a viewport RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Get the screen space position for a 3d world space position RLAPI Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int height); // Get size position for a 3d world space position RLAPI Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera); // Get the screen space position for a 2d camera world space position@@ -1162,16 +1163,17 @@ RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC) // Input-related functions: gamepads-RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available-RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id-RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once-RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed-RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once-RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed-RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed-RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad-RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis-RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB)+RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available+RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id+RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once+RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed+RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once+RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed+RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed+RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad+RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis+RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB)+RLAPI void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor); // Set gamepad vibration for both motors // Input-related functions: mouse RLAPI bool IsMouseButtonPressed(int button); // Check if a mouse button has been pressed once@@ -1407,8 +1409,9 @@ RLAPI void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draws a texture (or part of it) that stretches or shrinks nicely // Color/pixel related functions+RLAPI bool ColorIsEqual(Color col1, Color col2); // Check if two colors are equal RLAPI Color Fade(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f-RLAPI int ColorToInt(Color color); // Get hexadecimal value for a Color+RLAPI int ColorToInt(Color color); // Get hexadecimal value for a Color (0xRRGGBBAA) RLAPI Vector4 ColorNormalize(Color color); // Get Color normalized as float [0..1] RLAPI Color ColorFromNormalized(Vector4 normalized); // Get Color from normalized values [0..1] RLAPI Vector3 ColorToHSV(Color color); // Get HSV values for a Color, hue [0..360], saturation/value [0..1]@@ -1660,10 +1663,10 @@ RLAPI void SetAudioStreamBufferSizeDefault(int size); // Default size for new audio streams RLAPI void SetAudioStreamCallback(AudioStream stream, AudioCallback callback); // Audio thread callback to request new data -RLAPI void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream, receives the samples as <float>s+RLAPI void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream, receives the samples as 'float' RLAPI void DetachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Detach audio stream processor from stream -RLAPI void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline, receives the samples as <float>s+RLAPI void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline, receives the samples as 'float' RLAPI void DetachAudioMixedProcessor(AudioCallback processor); // Detach audio stream processor from the entire audio pipeline #if defined(__cplusplus)
raylib/src/raymath.h view
@@ -431,6 +431,28 @@ return result; } +// Get min value for each pair of components+RMAPI Vector2 Vector2Min(Vector2 v1, Vector2 v2)+{+ Vector2 result = { 0 };++ result.x = fminf(v1.x, v2.x);+ result.y = fminf(v1.y, v2.y);++ return result;+}++// Get max value for each pair of components+RMAPI Vector2 Vector2Max(Vector2 v1, Vector2 v2)+{+ Vector2 result = { 0 };++ result.x = fmaxf(v1.x, v2.x);+ result.y = fmaxf(v1.y, v2.y);++ return result;+}+ // Rotate vector by angle RMAPI Vector2 Vector2Rotate(Vector2 v, float angle) {@@ -524,6 +546,31 @@ return result; } +// Compute the direction of a refracted ray+// v: normalized direction of the incoming ray+// n: normalized normal vector of the interface of two optical media+// r: ratio of the refractive index of the medium from where the ray comes+// to the refractive index of the medium on the other side of the surface+RMAPI Vector2 Vector2Refract(Vector2 v, Vector2 n, float r)+{+ Vector2 result = { 0 };++ float dot = v.x*n.x + v.y*n.y;+ float d = 1.0f - r*r*(1.0f - dot*dot);++ if (d >= 0.0f)+ {+ d = sqrtf(d);+ v.x = r*v.x - (r*dot + d)*n.x;+ v.y = r*v.y - (r*dot + d)*n.y;++ result = v;+ }++ return result;+}++ //---------------------------------------------------------------------------------- // Module Functions Definition - Vector3 math //----------------------------------------------------------------------------------@@ -730,7 +777,7 @@ RMAPI Vector3 Vector3Project(Vector3 v1, Vector3 v2) { Vector3 result = { 0 };- + float v1dv2 = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); float v2dv2 = (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z); @@ -747,7 +794,7 @@ RMAPI Vector3 Vector3Reject(Vector3 v1, Vector3 v2) { Vector3 result = { 0 };- + float v1dv2 = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); float v2dv2 = (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z); @@ -875,6 +922,27 @@ return result; } +// Move Vector towards target+RMAPI Vector3 Vector3MoveTowards(Vector3 v, Vector3 target, float maxDistance)+{+ Vector3 result = { 0 };++ float dx = target.x - v.x;+ float dy = target.y - v.y;+ float dz = target.z - v.z;+ float value = (dx*dx) + (dy*dy) + (dz*dz);++ if ((value == 0) || ((maxDistance >= 0) && (value <= maxDistance*maxDistance))) return target;++ float dist = sqrtf(value);++ result.x = v.x + dx/dist*maxDistance;+ result.y = v.y + dy/dist*maxDistance;+ result.z = v.z + dz/dist*maxDistance;++ return result;+}+ // Calculate linear interpolation between two vectors RMAPI Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount) {@@ -1137,7 +1205,234 @@ return result; } + //----------------------------------------------------------------------------------+// Module Functions Definition - Vector4 math+//----------------------------------------------------------------------------------++RMAPI Vector4 Vector4Zero(void)+{+ Vector4 result = { 0.0f, 0.0f, 0.0f, 0.0f };+ return result;+}++RMAPI Vector4 Vector4One(void)+{+ Vector4 result = { 1.0f, 1.0f, 1.0f, 1.0f };+ return result;+}++RMAPI Vector4 Vector4Add(Vector4 v1, Vector4 v2)+{+ Vector4 result = {+ v1.x + v2.x,+ v1.y + v2.y,+ v1.z + v2.z,+ v1.w + v2.w+ };+ return result;+}++RMAPI Vector4 Vector4AddValue(Vector4 v, float add)+{+ Vector4 result = {+ v.x + add,+ v.y + add,+ v.z + add,+ v.w + add+ };+ return result;+}++RMAPI Vector4 Vector4Subtract(Vector4 v1, Vector4 v2)+{+ Vector4 result = {+ v1.x - v2.x,+ v1.y - v2.y,+ v1.z - v2.z,+ v1.w - v2.w+ };+ return result;+}++RMAPI Vector4 Vector4SubtractValue(Vector4 v, float add)+{+ Vector4 result = {+ v.x - add,+ v.y - add,+ v.z - add,+ v.w - add+ };+ return result;+}++RMAPI float Vector4Length(Vector4 v)+{+ float result = sqrtf((v.x*v.x) + (v.y*v.y) + (v.z*v.z) + (v.w*v.w));+ return result;+}++RMAPI float Vector4LengthSqr(Vector4 v)+{+ float result = (v.x*v.x) + (v.y*v.y) + (v.z*v.z) + (v.w*v.w);+ return result;+}++RMAPI float Vector4DotProduct(Vector4 v1, Vector4 v2)+{+ float result = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z + v1.w*v2.w);+ return result;+}++// Calculate distance between two vectors+RMAPI float Vector4Distance(Vector4 v1, Vector4 v2)+{+ float result = sqrtf(+ (v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y) ++ (v1.z - v2.z)*(v1.z - v2.z) + (v1.w - v2.w)*(v1.w - v2.w));+ return result;+}++// Calculate square distance between two vectors+RMAPI float Vector4DistanceSqr(Vector4 v1, Vector4 v2)+{+ float result =+ (v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y) ++ (v1.z - v2.z)*(v1.z - v2.z) + (v1.w - v2.w)*(v1.w - v2.w);++ return result;+}++RMAPI Vector4 Vector4Scale(Vector4 v, float scale)+{+ Vector4 result = { v.x*scale, v.y*scale, v.z*scale, v.w*scale };+ return result;+}++// Multiply vector by vector+RMAPI Vector4 Vector4Multiply(Vector4 v1, Vector4 v2)+{+ Vector4 result = { v1.x*v2.x, v1.y*v2.y, v1.z*v2.z, v1.w*v2.w };+ return result;+}++// Negate vector+RMAPI Vector4 Vector4Negate(Vector4 v)+{+ Vector4 result = { -v.x, -v.y, -v.z, -v.w };+ return result;+}++// Divide vector by vector+RMAPI Vector4 Vector4Divide(Vector4 v1, Vector4 v2)+{+ Vector4 result = { v1.x/v2.x, v1.y/v2.y, v1.z/v2.z, v1.w/v2.w };+ return result;+}++// Normalize provided vector+RMAPI Vector4 Vector4Normalize(Vector4 v)+{+ Vector4 result = { 0 };+ float length = sqrtf((v.x*v.x) + (v.y*v.y) + (v.z*v.z) + (v.w*v.w));++ if (length > 0)+ {+ float ilength = 1.0f/length;+ result.x = v.x*ilength;+ result.y = v.y*ilength;+ result.z = v.z*ilength;+ result.w = v.w*ilength;+ }++ return result;+}++// Get min value for each pair of components+RMAPI Vector4 Vector4Min(Vector4 v1, Vector4 v2)+{+ Vector4 result = { 0 };++ result.x = fminf(v1.x, v2.x);+ result.y = fminf(v1.y, v2.y);+ result.z = fminf(v1.z, v2.z);+ result.w = fminf(v1.w, v2.w);++ return result;+}++// Get max value for each pair of components+RMAPI Vector4 Vector4Max(Vector4 v1, Vector4 v2)+{+ Vector4 result = { 0 };++ result.x = fmaxf(v1.x, v2.x);+ result.y = fmaxf(v1.y, v2.y);+ result.z = fmaxf(v1.z, v2.z);+ result.w = fmaxf(v1.w, v2.w);++ return result;+}++// Calculate linear interpolation between two vectors+RMAPI Vector4 Vector4Lerp(Vector4 v1, Vector4 v2, float amount)+{+ Vector4 result = { 0 };++ result.x = v1.x + amount*(v2.x - v1.x);+ result.y = v1.y + amount*(v2.y - v1.y);+ result.z = v1.z + amount*(v2.z - v1.z);+ result.w = v1.w + amount*(v2.w - v1.w);++ return result;+}++// Move Vector towards target+RMAPI Vector4 Vector4MoveTowards(Vector4 v, Vector4 target, float maxDistance)+{+ Vector4 result = { 0 };++ float dx = target.x - v.x;+ float dy = target.y - v.y;+ float dz = target.z - v.z;+ float dw = target.w - v.w;+ float value = (dx*dx) + (dy*dy) + (dz*dz) + (dw*dw);++ if ((value == 0) || ((maxDistance >= 0) && (value <= maxDistance*maxDistance))) return target;++ float dist = sqrtf(value);++ result.x = v.x + dx/dist*maxDistance;+ result.y = v.y + dy/dist*maxDistance;+ result.z = v.z + dz/dist*maxDistance;+ result.w = v.w + dw/dist*maxDistance;++ return result;+}++// Invert the given vector+RMAPI Vector4 Vector4Invert(Vector4 v)+{+ Vector4 result = { 1.0f/v.x, 1.0f/v.y, 1.0f/v.z, 1.0f/v.w };+ return result;+}++// Check whether two given vectors are almost equal+RMAPI int Vector4Equals(Vector4 p, Vector4 q)+{+#if !defined(EPSILON)+ #define EPSILON 0.000001f+#endif++ int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) &&+ ((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) &&+ ((fabsf(p.z - q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) &&+ ((fabsf(p.w - q.w)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w)))));+ return result;+}+++//---------------------------------------------------------------------------------- // Module Functions Definition - Matrix math //---------------------------------------------------------------------------------- @@ -2043,8 +2338,7 @@ float ilength = 0.0f; // Vector3Normalize(axis)- Vector3 v = axis;- length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);+ length = axisLength; if (length == 0.0f) length = 1.0f; ilength = 1.0f/length; axis.x *= ilength;
raylib/src/rcore.c view
@@ -118,12 +118,12 @@ #if defined(SUPPORT_GESTURES_SYSTEM) #define RGESTURES_IMPLEMENTATION- #include "rgestures.h" // Gestures detection functionality+ #include "rgestures.h" // Gestures detection functionality #endif #if defined(SUPPORT_CAMERA_SYSTEM) #define RCAMERA_IMPLEMENTATION- #include "rcamera.h" // Camera system functionality+ #include "rcamera.h" // Camera system functionality #endif #if defined(SUPPORT_GIF_RECORDING)@@ -224,6 +224,9 @@ #ifndef MAX_GAMEPAD_BUTTONS #define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) #endif+#ifndef MAX_GAMEPAD_VIBRATION_TIME+ #define MAX_GAMEPAD_VIBRATION_TIME 2.0f // Maximum vibration time in seconds+#endif #ifndef MAX_TOUCH_POINTS #define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported #endif@@ -289,16 +292,16 @@ struct { struct { int exitKey; // Default exit key- char currentKeyState[MAX_KEYBOARD_KEYS]; // Registers current frame key state- char previousKeyState[MAX_KEYBOARD_KEYS]; // Registers previous frame key state+ char currentKeyState[MAX_KEYBOARD_KEYS]; // Registers current frame key state+ char previousKeyState[MAX_KEYBOARD_KEYS]; // Registers previous frame key state // NOTE: Since key press logic involves comparing prev vs cur key state, we need to handle key repeats specially- char keyRepeatInFrame[MAX_KEYBOARD_KEYS]; // Registers key repeats for current frame.+ char keyRepeatInFrame[MAX_KEYBOARD_KEYS]; // Registers key repeats for current frame. - int keyPressedQueue[MAX_KEY_PRESSED_QUEUE]; // Input keys queue+ int keyPressedQueue[MAX_KEY_PRESSED_QUEUE]; // Input keys queue int keyPressedQueueCount; // Input keys queue count - int charPressedQueue[MAX_CHAR_PRESSED_QUEUE]; // Input characters queue (unicode)+ int charPressedQueue[MAX_CHAR_PRESSED_QUEUE]; // Input characters queue (unicode) int charPressedQueueCount; // Input characters queue count } Keyboard;@@ -328,7 +331,7 @@ } Touch; struct { int lastButtonPressed; // Register last gamepad button pressed- int axisCount[MAX_GAMEPADS]; // Register number of available gamepad axis+ int axisCount[MAX_GAMEPADS]; // Register number of available gamepad axis bool ready[MAX_GAMEPADS]; // Flag to know if gamepad is ready char name[MAX_GAMEPADS][64]; // Gamepad name holder char currentButtonState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Current gamepad buttons state@@ -846,23 +849,33 @@ // Draw record indicator if (gifRecording) {+ #ifndef GIF_RECORD_FRAMERATE #define GIF_RECORD_FRAMERATE 10- gifFrameCounter++;+ #endif+ gifFrameCounter += GetFrameTime()*1000; - // NOTE: We record one gif frame every 10 game frames- if ((gifFrameCounter%GIF_RECORD_FRAMERATE) == 0)+ // NOTE: We record one gif frame depending on the desired gif framerate+ if (gifFrameCounter > 1000/GIF_RECORD_FRAMERATE) { // Get image data for the current frame (from backbuffer) // NOTE: This process is quite slow... :( Vector2 scale = GetWindowScaleDPI(); unsigned char *screenData = rlReadScreenPixels((int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y));- msf_gif_frame(&gifState, screenData, 10, 16, (int)((float)CORE.Window.render.width*scale.x)*4); + #ifndef GIF_RECORD_BITRATE+ #define GIF_RECORD_BITRATE 16+ #endif++ // Add the frame to the gif recording, given how many frames have passed in centiseconds+ msf_gif_frame(&gifState, screenData, gifFrameCounter/10, GIF_RECORD_BITRATE, (int)((float)CORE.Window.render.width*scale.x)*4);+ gifFrameCounter -= 1000/GIF_RECORD_FRAMERATE;+ RL_FREE(screenData); // Free image data } #if defined(SUPPORT_MODULE_RSHAPES) && defined(SUPPORT_MODULE_RTEXT)- if (((gifFrameCounter/15)%2) == 1)+ // Display the recording indicator every half-second+ if ((int)(GetTime()/0.5)%2 == 1) { DrawCircle(30, CORE.Window.screen.height - 20, 10, MAROON); // WARNING: Module required: rshapes DrawText("GIF RECORDING", 50, CORE.Window.screen.height - 25, 10, RED); // WARNING: Module required: rtext@@ -1403,21 +1416,21 @@ // Module Functions Definition: Screen-space Queries //---------------------------------------------------------------------------------- -// Get a ray trace from mouse position-Ray GetMouseRay(Vector2 mousePosition, Camera camera)+// Get a ray trace from screen position (i.e mouse)+Ray GetScreenToWorldRay(Vector2 position, Camera camera) {- return GetViewRay(mousePosition, camera, (float)GetScreenWidth(), (float)GetScreenHeight());+ return GetScreenToWorldRayEx(position, camera, GetScreenWidth(), GetScreenHeight()); } -// Get a ray trace from the mouse position within a specific section of the screen-Ray GetViewRay(Vector2 mousePosition, Camera camera, float width, float height)+// Get a ray trace from the screen position (i.e mouse) within a specific section of the screen+Ray GetScreenToWorldRayEx(Vector2 position, Camera camera, int width, int height) { Ray ray = { 0 }; // Calculate normalized device coordinates // NOTE: y value is negative- float x = (2.0f*mousePosition.x)/width - 1.0f;- float y = 1.0f - (2.0f*mousePosition.y)/height;+ float x = (2.0f*position.x)/(float)width - 1.0f;+ float y = 1.0f - (2.0f*position.y)/(float)height; float z = 1.0f; // Store values in a vector@@ -1796,7 +1809,7 @@ char path[512] = { 0 }; strcpy(path, TextFormat("%s/%s", CORE.Storage.basePath, GetFileName(fileName)));- + ExportImage(image, path); // WARNING: Module required: rtextures RL_FREE(imgData); @@ -1952,7 +1965,7 @@ const char *GetFileNameWithoutExt(const char *filePath) { #define MAX_FILENAME_LENGTH 256- + static char fileName[MAX_FILENAME_LENGTH] = { 0 }; memset(fileName, 0, MAX_FILENAME_LENGTH); @@ -1960,7 +1973,7 @@ { strcpy(fileName, GetFileName(filePath)); // Get filename.ext without path int size = (int)strlen(fileName); // Get size in bytes- + for (int i = size; i > 0; i--) // Reverse search '.' { if (fileName[i] == '.')@@ -1971,7 +1984,7 @@ } } }- + return fileName; }
raylib/src/rglfw.c view
@@ -34,8 +34,8 @@ // _GLFW_X11 to use the X Window System // _GLFW_WAYLAND to use the Wayland API (experimental and incomplete) // _GLFW_COCOA to use the Cocoa frameworks-// _GLFW_OSMESA to use the OSMesa API (headless and non-interactive)-// _GLFW_MIR experimental, not supported at this moment+//+// On Linux, _GLFW_X11 and _GLFW_WAYLAND can be combined //---------------------------------------------------------------------------------- // Feature Test Macros required for this module@@ -53,8 +53,8 @@ #define _GLFW_WIN32 #endif #if defined(__linux__)- #if !defined(_GLFW_WAYLAND) // Required for Wayland windowing- #define _GLFW_X11+ #if !defined(_GLFW_WAYLAND) && !defined(_GLFW_X11)+ #error "Cannot disable Wayland and X11 at the same time" #endif #endif #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
raylib/src/rlgl.h view
@@ -623,7 +623,7 @@ RLAPI unsigned int rlGetActiveFramebuffer(void); // Get the currently active render texture (fbo), 0 for default framebuffer RLAPI void rlActiveDrawBuffers(int count); // Activate multiple draw color buffers RLAPI void rlBlitFramebuffer(int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth, int dstHeight, int bufferMask); // Blit active framebuffer to main framebuffer-RLAPI void rlBindFramebuffer(unsigned int target, unsigned int framebuffer); // Bind framebuffer (FBO) +RLAPI void rlBindFramebuffer(unsigned int target, unsigned int framebuffer); // Bind framebuffer (FBO) // General render state RLAPI void rlEnableColorBlend(void); // Enable color blending@@ -903,6 +903,14 @@ #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE #endif +#ifndef GL_PROGRAM_POINT_SIZE+ #define GL_PROGRAM_POINT_SIZE 0x8642+#endif++#ifndef GL_LINE_WIDTH+ #define GL_LINE_WIDTH 0x0B21+#endif+ #if defined(GRAPHICS_API_OPENGL_11) #define GL_UNSIGNED_SHORT_5_6_5 0x8363 #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034@@ -3820,8 +3828,8 @@ { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // NOTE: Data type could be: GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT- // Additional types (depends on OpenGL version or extensions): - // - GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, GL_FIXED, + // Additional types (depends on OpenGL version or extensions):+ // - GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, GL_FIXED, // - GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_10F_11F_11F_REV glVertexAttribPointer(index, compSize, type, normalized, stride, pointer); #endif
raylib/src/rmodels.c view
@@ -54,8 +54,8 @@ #include "raymath.h" // Required for: Vector3, Quaternion and Matrix functionality #include <stdio.h> // Required for: sprintf()-#include <stdlib.h> // Required for: malloc(), free()-#include <string.h> // Required for: memcmp(), strlen()+#include <stdlib.h> // Required for: malloc(), calloc(), free()+#include <string.h> // Required for: memcmp(), strlen(), strncpy() #include <math.h> // Required for: sinf(), cosf(), sqrtf(), fabsf() #if defined(SUPPORT_FILEFORMAT_OBJ) || defined(SUPPORT_FILEFORMAT_MTL)@@ -1470,9 +1470,6 @@ if (mesh.indices != NULL) rlEnableVertexBufferElement(mesh.vboId[6]); } - // WARNING: Disable vertex attribute color input if mesh can not provide that data (despite location being enabled in shader)- if (mesh.vboId[3] == 0) rlDisableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);- int eyeCount = 1; if (rlIsStereoRenderEnabled()) eyeCount = 2; @@ -1691,9 +1688,6 @@ if (mesh.indices != NULL) rlEnableVertexBufferElement(mesh.vboId[6]); } - // WARNING: Disable vertex attribute color input if mesh can not provide that data (despite location being enabled in shader)- if (mesh.vboId[3] == 0) rlDisableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);- int eyeCount = 1; if (rlIsStereoRenderEnabled()) eyeCount = 2; @@ -1883,7 +1877,7 @@ byteCount += sprintf(txtData + byteCount, "// Mesh basic information\n"); byteCount += sprintf(txtData + byteCount, "#define %s_VERTEX_COUNT %i\n", varFileName, mesh.vertexCount); byteCount += sprintf(txtData + byteCount, "#define %s_TRIANGLE_COUNT %i\n\n", varFileName, mesh.triangleCount);- + // Define vertex attributes data as separate arrays //----------------------------------------------------------------------------------------- if (mesh.vertices != NULL) // Vertex position (XYZ - 3 components per vertex - float)@@ -1892,28 +1886,28 @@ for (int i = 0; i < mesh.vertexCount*3 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.vertices[i]); byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.vertices[mesh.vertexCount*3 - 1]); }- - if (mesh.texcoords != NULL) // Vertex texture coordinates (UV - 2 components per vertex - float) ++ if (mesh.texcoords != NULL) // Vertex texture coordinates (UV - 2 components per vertex - float) { byteCount += sprintf(txtData + byteCount, "static float %s_TEXCOORD_DATA[%i] = { ", varFileName, mesh.vertexCount*2); for (int i = 0; i < mesh.vertexCount*2 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.texcoords[i]); byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.texcoords[mesh.vertexCount*2 - 1]); }- - if (mesh.texcoords2 != NULL) // Vertex texture coordinates (UV - 2 components per vertex - float) ++ if (mesh.texcoords2 != NULL) // Vertex texture coordinates (UV - 2 components per vertex - float) { byteCount += sprintf(txtData + byteCount, "static float %s_TEXCOORD2_DATA[%i] = { ", varFileName, mesh.vertexCount*2); for (int i = 0; i < mesh.vertexCount*2 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.texcoords2[i]); byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.texcoords2[mesh.vertexCount*2 - 1]); }- + if (mesh.normals != NULL) // Vertex normals (XYZ - 3 components per vertex - float) { byteCount += sprintf(txtData + byteCount, "static float %s_NORMAL_DATA[%i] = { ", varFileName, mesh.vertexCount*3); for (int i = 0; i < mesh.vertexCount*3 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.normals[i]); byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.normals[mesh.vertexCount*3 - 1]); }- + if (mesh.tangents != NULL) // Vertex tangents (XYZW - 4 components per vertex - float) { byteCount += sprintf(txtData + byteCount, "static float %s_TANGENT_DATA[%i] = { ", varFileName, mesh.vertexCount*4);@@ -4050,7 +4044,7 @@ model.meshCount = meshCount; // Set number of materials available- // NOTE: There could be more materials available than meshes but it will be resolved at + // NOTE: There could be more materials available than meshes but it will be resolved at // model.meshMaterial, just assigning the right material to corresponding mesh model.materialCount = materialCount; if (model.materialCount == 0)@@ -4068,7 +4062,7 @@ for (int i = 0; i < model.meshCount; i++) { // WARNING: We need to calculate the mesh triangles manually using meshes[i].face_offset- // because in case of triangulated quads, meshes[i].length actually report quads, + // because in case of triangulated quads, meshes[i].length actually report quads, // despite the triangulation that is efectively considered on attrib.num_faces unsigned int tris = 0; if (i == model.meshCount - 1) tris = attrib.num_faces - meshes[i].face_offset;@@ -5282,22 +5276,38 @@ } else if ((attribute->component_type == cgltf_component_type_r_16u) && (attribute->type == cgltf_type_vec2)) {+ // TODO: WARNING: model.meshes[].boneIds is an (unsigned char *) --> Conversion required!+ // Handle 16-bit unsigned short, vec2 format model.meshes[meshIndex].boneIds = RL_CALLOC(model.meshes[meshIndex].vertexCount*2, sizeof(unsigned short));- unsigned short* ptr = (unsigned short*)model.meshes[meshIndex].boneIds;+ unsigned short *ptr = (unsigned short *)model.meshes[meshIndex].boneIds; LOAD_ATTRIBUTE(attribute, 2, unsigned short, ptr) }+ else if ((attribute->component_type == cgltf_component_type_r_16u) && (attribute->type == cgltf_type_vec4))+ {+ // TODO: WARNING: model.meshes[].boneIds is an (unsigned char *) --> Conversion required!++ // Handle 16-bit unsigned short, vec4 format+ model.meshes[meshIndex].boneIds = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned short));+ unsigned short *ptr = (unsigned short *)model.meshes[meshIndex].boneIds;+ LOAD_ATTRIBUTE(attribute, 4, unsigned short, ptr)+ } else if ((attribute->component_type == cgltf_component_type_r_32u) && (attribute->type == cgltf_type_vec4)) {+ // TODO: WARNING: model.meshes[].boneIds is an (unsigned char *) --> Conversion required!+ // Handle 32-bit unsigned int, vec4 format model.meshes[meshIndex].boneIds = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned int));- LOAD_ATTRIBUTE(attribute, 4, unsigned int, model.meshes[meshIndex].boneIds)+ unsigned int *ptr = (unsigned int *)model.meshes[meshIndex].boneIds;+ LOAD_ATTRIBUTE(attribute, 4, unsigned int, ptr) } else if ((attribute->component_type == cgltf_component_type_r_32f) && (attribute->type == cgltf_type_vec2)) {+ // TODO: WARNING: model.meshes[].boneIds is an (unsigned char *) --> Conversion required!+ // Handle 32-bit float, vec2 format model.meshes[meshIndex].boneIds = RL_CALLOC(model.meshes[meshIndex].vertexCount*2, sizeof(float));- float* ptr = (float*)model.meshes[meshIndex].boneIds;+ float *ptr = (float *)model.meshes[meshIndex].boneIds; LOAD_ATTRIBUTE(attribute, 2, float, ptr) } else TRACELOG(LOG_WARNING, "MODEL: [%s] Joint attribute data format not supported", fileName);@@ -5625,6 +5635,7 @@ // 6*4 = 12 vertices per voxel Vector3 *pvertices = (Vector3 *)voxarray.vertices.array;+ Vector3 *pnormals = (Vector3 *)voxarray.normals.array; Color *pcolors = (Color *)voxarray.colors.array; unsigned short *pindices = voxarray.indices.array; // 5461*6*6 = 196596 indices max per mesh@@ -5640,12 +5651,16 @@ pmesh->vertexCount = (int)fmin(verticesMax, verticesRemain); size = pmesh->vertexCount*sizeof(float)*3;- pmesh->vertices = RL_MALLOC(size);+ pmesh->vertices = (float *)RL_MALLOC(size); memcpy(pmesh->vertices, pvertices, size); + // Copy normals+ pmesh->normals = (float *)RL_MALLOC(size);+ memcpy(pmesh->normals, pnormals, size);+ // Copy indices size = voxarray.indices.used*sizeof(unsigned short);- pmesh->indices = RL_MALLOC(size);+ pmesh->indices = (unsigned short *)RL_MALLOC(size); memcpy(pmesh->indices, pindices, size); pmesh->triangleCount = (pmesh->vertexCount/4)*2;@@ -5660,6 +5675,7 @@ verticesRemain -= verticesMax; pvertices += verticesMax;+ pnormals += verticesMax; pcolors += verticesMax; } @@ -5789,6 +5805,12 @@ // M3D specs only consider vertex colors if no material is provided, however raylib uses both and mixes the colors if ((mi == M3D_UNDEF) || vcolor) model.meshes[k].colors = RL_CALLOC(model.meshes[k].vertexCount*4, sizeof(unsigned char)); + // If no map is provided and we allocated vertex colors, set them to white+ if ((mi == M3D_UNDEF) && (model.meshes[k].colors != NULL))+ {+ for (int c = 0; c < model.meshes[k].vertexCount*4; c++) model.meshes[k].colors[c] = 255;+ }+ if (m3d->numbone && m3d->numskin) { model.meshes[k].boneIds = (unsigned char *)RL_CALLOC(model.meshes[k].vertexCount*4, sizeof(unsigned char));@@ -6052,8 +6074,9 @@ animations[a].boneCount = m3d->numbone + 1; animations[a].bones = RL_MALLOC((m3d->numbone + 1)*sizeof(BoneInfo)); animations[a].framePoses = RL_MALLOC(animations[a].frameCount*sizeof(Transform *));- strncpy(animations[a].name, m3d->action[a].name, sizeof(animations[a].name));- animations[a].name[sizeof(animations[a].name) - 1] = '\0';+ strncpy(animations[a].name, m3d->action[a].name, sizeof(animations[a].name));+ animations[a].name[sizeof(animations[a].name) - 1] = '\0';+ TRACELOG(LOG_INFO, "MODEL: [%s] animation #%i: %i msec, %i frames", fileName, a, m3d->action[a].durationmsec, animations[a].frameCount); for (i = 0; i < (int)m3d->numbone; i++)
raylib/src/rshapes.c view
@@ -338,7 +338,7 @@ } // NOTE: In case number of segments is odd, we add one last piece to the cake- if ((segments%2) == 1)+ if (((unsigned int)segments%2) == 1) { rlColor4ub(color.r, color.g, color.b, color.a); @@ -1574,7 +1574,7 @@ #if defined(SUPPORT_SPLINE_MITERS) Vector2 prevNormal = (Vector2){-(points[1].y - points[0].y), (points[1].x - points[0].x)}; float prevLength = sqrtf(prevNormal.x*prevNormal.x + prevNormal.y*prevNormal.y);- + if (prevLength > 0.0f) { prevNormal.x /= prevLength;@@ -1587,7 +1587,7 @@ } Vector2 prevRadius = { 0.5f*thick*prevNormal.x, 0.5f*thick*prevNormal.y };- + for (int i = 0; i < pointCount - 1; i++) { Vector2 normal = { 0 };@@ -1596,7 +1596,7 @@ { normal = (Vector2){-(points[i + 2].y - points[i + 1].y), (points[i + 2].x - points[i + 1].x)}; float normalLength = sqrtf(normal.x*normal.x + normal.y*normal.y);- + if (normalLength > 0.0f) { normal.x /= normalLength;@@ -1615,7 +1615,7 @@ Vector2 radius = { prevNormal.x + normal.x, prevNormal.y + normal.y }; float radiusLength = sqrtf(radius.x*radius.x + radius.y*radius.y);- + if (radiusLength > 0.0f) { radius.x /= radiusLength;@@ -1639,7 +1639,7 @@ radius.x = 0.0f; radius.y = 0.0f; }- + Vector2 strip[4] = { { points[i].x - prevRadius.x, points[i].y - prevRadius.y }, { points[i].x + prevRadius.x, points[i].y + prevRadius.y },@@ -1677,7 +1677,7 @@ DrawTriangleStrip(strip, 4, color); } #endif- + #if defined(SUPPORT_SPLINE_SEGMENT_CAPS) // TODO: Add spline segment rounded caps at the begin/end of the spline #endif
raylib/src/rtext.c view
@@ -536,7 +536,7 @@ font.glyphCount = (codepointCount > 0)? codepointCount : 95; font.glyphPadding = 0; -#if defined(SUPPORT_FILEFORMAT_TTF) +#if defined(SUPPORT_FILEFORMAT_TTF) if (TextIsEqual(fileExtLower, ".ttf") || TextIsEqual(fileExtLower, ".otf")) {@@ -1468,10 +1468,10 @@ if (text[0] == '-') sign = -1.0f; text++; }- + int i = 0; for (; ((text[i] >= '0') && (text[i] <= '9')); i++) value = value*10.0f + (float)(text[i] - '0');- + if (text[i++] != '.') value *= sign; else {@@ -1482,7 +1482,7 @@ divisor = divisor*10.0f; } }- + return value; } @@ -2275,7 +2275,7 @@ static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, int *codepoints, int codepointCount, int *outFontSize) { #define MAX_BUFFER_SIZE 256- + char buffer[MAX_BUFFER_SIZE] = { 0 }; GlyphInfo *glyphs = NULL;@@ -2289,7 +2289,7 @@ const char *fileTextPtr = fileText; bool fontMalformed = false; // Is the font malformed- bool fontStarted = false; // Has font started (STARTFONT) + bool fontStarted = false; // Has font started (STARTFONT) int fontBBw = 0; // Font base character bounding box width int fontBBh = 0; // Font base character bounding box height int fontBBxoff0 = 0; // Font base character bounding box X0 offset@@ -2300,7 +2300,7 @@ bool charBitmapStarted = false; // Has bitmap data started (BITMAP) int charBitmapNextRow = 0; // Y position for the next row of bitmap data int charEncoding = -1; // The unicode value of the character (-1 if not set)- int charBBw = 0; // Character bounding box width + int charBBw = 0; // Character bounding box width int charBBh = 0; // Character bounding box height int charBBxoff0 = 0; // Character bounding box X0 offset int charBByoff0 = 0; // Character bounding box Y0 offset@@ -2347,17 +2347,17 @@ if (charGlyphInfo != NULL) { int pixelY = charBitmapNextRow++;- + if (pixelY >= charGlyphInfo->image.height) break; for (int x = 0; x < readBytes; x++) { unsigned char byte = HexToInt(buffer[x]);- + for (int bitX = 0; bitX < 4; bitX++) { int pixelX = ((x*4) + bitX);- + if (pixelX >= charGlyphInfo->image.width) break; if ((byte & (8 >> bitX)) > 0) ((unsigned char *)charGlyphInfo->image.data)[(pixelY*charGlyphInfo->image.width) + pixelX] = 255;@@ -2393,7 +2393,7 @@ { // Search for glyph index in codepoints charGlyphInfo = NULL;- + for (int codepointIndex = 0; codepointIndex < codepointCount; codepointIndex++) { if (codepoints[codepointIndex] == charEncoding)
raylib/src/rtextures.c view
@@ -681,10 +681,11 @@ // Load image from screen buffer and (screenshot) Image LoadImageFromScreen(void) {+ Vector2 scale = GetWindowScaleDPI(); Image image = { 0 }; - image.width = GetScreenWidth();- image.height = GetScreenHeight();+ image.width = GetScreenWidth()*scale.x;+ image.height = GetScreenHeight()*scale.y; image.mipmaps = 1; image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; image.data = rlReadScreenPixels(image.width, image.height);@@ -1056,6 +1057,7 @@ } // Generate image: white noise+// NOTE: It requires GetRandomValue(), defined in [rcore] Image GenImageWhiteNoise(int width, int height, float factor) { Color *pixels = (Color *)RL_MALLOC(width*height*sizeof(Color));@@ -2138,7 +2140,7 @@ if ((image->data == NULL) || (image->width == 0) || (image->height == 0) || kernel == NULL) return; int kernelWidth = (int)sqrtf((float)kernelSize);- + if (kernelWidth*kernelWidth != kernelSize) { TRACELOG(LOG_WARNING, "IMAGE: Convolution kernel must be square to be applied");@@ -2164,7 +2166,7 @@ float aRes = 0.0f; int startRange = 0, endRange = 0;- + if (kernelWidth%2 == 0) { startRange = -kernelWidth/2;@@ -2175,7 +2177,7 @@ startRange = -kernelWidth/2; endRange = kernelWidth/2 + 1; }- + for(int x = 0; x < image->height; x++) { for (int y = 0; y < image->width; y++)@@ -2187,14 +2189,14 @@ int xkabs = xk + kernelWidth/2; int ykabs = yk + kernelWidth/2; unsigned int imgindex = image->width*(x + xk) + (y + yk);- + if (imgindex >= (unsigned int)(image->width*image->height)) { temp[kernelWidth * xkabs + ykabs].x = 0.0f; temp[kernelWidth * xkabs + ykabs].y = 0.0f; temp[kernelWidth * xkabs + ykabs].z = 0.0f; temp[kernelWidth * xkabs + ykabs].w = 0.0f;- } + } else { temp[kernelWidth * xkabs + ykabs].x = ((float)pixels[imgindex].r)/255.0f*kernel[kernelWidth*xkabs + ykabs];@@ -2244,7 +2246,7 @@ for (int i = 0; i < (image->width*image->height); i++) { float alpha = (float)imageCopy2[i].w;- + pixels[i].r = (unsigned char)((imageCopy2[i].x)*255.0f); pixels[i].g = (unsigned char)((imageCopy2[i].y)*255.0f); pixels[i].b = (unsigned char)((imageCopy2[i].z)*255.0f);@@ -3874,9 +3876,14 @@ // NOTE: Cubemap data is expected to be provided as 6 images in a single data array, // one after the other (that's a vertical image), following convention: +X, -X, +Y, -Y, +Z, -Z cubemap.id = rlLoadTextureCubemap(faces.data, size, faces.format);- if (cubemap.id == 0) TRACELOG(LOG_WARNING, "IMAGE: Failed to load cubemap image");- else cubemap.mipmaps = 1; + if (cubemap.id != 0)+ {+ cubemap.format = faces.format;+ cubemap.mipmaps = 1;+ }+ else TRACELOG(LOG_WARNING, "IMAGE: Failed to load cubemap image");+ UnloadImage(faces); } else TRACELOG(LOG_WARNING, "IMAGE: Failed to detect cubemap image layout");@@ -4445,6 +4452,16 @@ rlSetTexture(0); }+}++// Check if two colors are equal+bool ColorIsEqual(Color col1, Color col2)+{+ bool result = false;++ if ((col1.r == col2.r) && (col1.g == col2.g) && (col1.b == col2.b) && (col1.a == col2.a)) result = true;++ return result; } // Get color with alpha applied, alpha goes from 0.0f to 1.0f
raylib/src/utils.c view
@@ -211,13 +211,13 @@ { // NOTE: fread() returns number of read elements instead of bytes, so we read [1 byte, size elements] size_t count = fread(data, sizeof(unsigned char), size, file);- + // WARNING: fread() returns a size_t value, usually 'unsigned int' (32bit compilation) and 'unsigned long long' (64bit compilation) // dataSize is unified along raylib as a 'int' type, so, for file-sizes > INT_MAX (2147483647 bytes) we have a limitation if (count > 2147483647) { TRACELOG(LOG_WARNING, "FILEIO: [%s] File is bigger than 2147483647 bytes, avoid using LoadFileData()", fileName);- + RL_FREE(data); data = NULL; }@@ -313,10 +313,16 @@ byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n"); - // Get file name from path and convert variable name to uppercase+ // Get file name from path char varFileName[256] = { 0 }; strcpy(varFileName, GetFileNameWithoutExt(fileName));- for (int i = 0; varFileName[i] != '\0'; i++) if ((varFileName[i] >= 'a') && (varFileName[i] <= 'z')) { varFileName[i] = varFileName[i] - 32; }+ for (int i = 0; varFileName[i] != '\0'; i++)+ {+ // Convert variable name to uppercase+ if ((varFileName[i] >= 'a') && (varFileName[i] <= 'z')) { varFileName[i] = varFileName[i] - 32; }+ // Replace non valid character for C identifier with '_'+ else if (varFileName[i] == '.' || varFileName[i] == '-' || varFileName[i] == '?' || varFileName[i] == '!' || varFileName[i] == '+') { varFileName[i] = '_'; }+ } byteCount += sprintf(txtData + byteCount, "#define %s_DATA_SIZE %i\n\n", varFileName, dataSize);
src/Raylib/Core.hs view
@@ -92,8 +92,8 @@ setShaderValueMatrix, setShaderValueTexture, unloadShader,- getMouseRay,- getViewRay,+ getScreenToWorldRay,+ getScreenToWorldRayEx, getCameraMatrix, getCameraMatrix2D, getWorldToScreen,@@ -171,6 +171,7 @@ getGamepadAxisCount, getGamepadAxisMovement, setGamepadMappings,+ setGamepadVibration, isMouseButtonPressed, isMouseButtonDown, isMouseButtonReleased,@@ -286,8 +287,8 @@ c'setShaderValueMatrix, c'setShaderValueTexture, c'unloadShader,- c'getMouseRay,- c'getViewRay,+ c'getScreenToWorldRay,+ c'getScreenToWorldRayEx, c'getCameraMatrix, c'getCameraMatrix2D, c'getWorldToScreen,@@ -369,6 +370,7 @@ c'getGamepadAxisCount, c'getGamepadAxisMovement, c'setGamepadMappings,+ c'setGamepadVibration, c'isMouseButtonPressed, c'isMouseButtonDown, c'isMouseButtonReleased,@@ -414,12 +416,15 @@ import Foreign ( Ptr, Storable (peek, poke, sizeOf),+ castFunPtr, castPtr,+ finalizeForeignPtr, fromBool, malloc, newArray, peekArray,- toBool, castFunPtr,+ toBool,+ withForeignPtr, ) import Foreign.C ( CBool (..),@@ -435,8 +440,8 @@ withCString, ) import Foreign.Ptr (nullPtr)-import Raylib.Internal (WindowResources, addAutomationEventList, addShaderId, defaultWindowResources, shaderLocations, unloadAutomationEventLists, unloadFrameBuffers, unloadShaders, unloadSingleAutomationEventList, unloadSingleShader, unloadTextures, unloadVaoIds, unloadVboIds, addFunPtr, unloadFunPtrs)-import Raylib.Internal.Foreign (c'free, configsToBitflag, pop, popCArray, popCString, withFreeable, withFreeableArray, withFreeableArrayLen, withMaybeCString)+import Raylib.Internal (WindowResources, addAutomationEventList, addFunPtr, addShaderId, defaultWindowResources, shaderLocations, unloadAutomationEventLists, unloadFrameBuffers, unloadFunPtrs, unloadShaders, unloadSingleAutomationEventList, unloadSingleShader, unloadTextures, unloadVaoIds, unloadVboIds)+import Raylib.Internal.Foreign (configsToBitflag, pop, popCArray, popCString, withFreeable, withFreeableArray, withFreeableArrayLen, withMaybeCString) import Raylib.Internal.TH (genNative) import Raylib.Types ( AutomationEvent,@@ -566,8 +571,8 @@ ("c'setShaderValueMatrix", "SetShaderValueMatrix_", "rl_bindings.h", [t|Ptr Shader -> CInt -> Ptr Matrix -> IO ()|], False), ("c'setShaderValueTexture", "SetShaderValueTexture_", "rl_bindings.h", [t|Ptr Shader -> CInt -> Ptr Texture -> IO ()|], False), ("c'unloadShader", "UnloadShader_", "rl_bindings.h", [t|Ptr Shader -> IO ()|], False),- ("c'getMouseRay", "GetMouseRay_", "rl_bindings.h", [t|Ptr Vector2 -> Ptr Camera3D -> IO (Ptr Ray)|], False),- ("c'getViewRay", "GetViewRay_", "rl_bindings.h", [t|Ptr Vector2 -> Ptr Camera3D -> CFloat -> CFloat -> IO (Ptr Ray)|], False),+ ("c'getScreenToWorldRay", "GetScreenToWorldRay_", "rl_bindings.h", [t|Ptr Vector2 -> Ptr Camera3D -> IO (Ptr Ray)|], False),+ ("c'getScreenToWorldRayEx", "GetScreenToWorldRayEx_", "rl_bindings.h", [t|Ptr Vector2 -> Ptr Camera3D -> CFloat -> CFloat -> IO (Ptr Ray)|], False), ("c'getCameraMatrix", "GetCameraMatrix_", "rl_bindings.h", [t|Ptr Camera3D -> IO (Ptr Matrix)|], False), ("c'getCameraMatrix2D", "GetCameraMatrix2D_", "rl_bindings.h", [t|Ptr Camera2D -> IO (Ptr Matrix)|], False), ("c'getWorldToScreen", "GetWorldToScreen_", "rl_bindings.h", [t|Ptr Vector3 -> Ptr Camera3D -> IO (Ptr Vector2)|], False),@@ -649,6 +654,7 @@ ("c'getGamepadAxisCount", "GetGamepadAxisCount_", "rl_bindings.h", [t|CInt -> IO CInt|], False), ("c'getGamepadAxisMovement", "GetGamepadAxisMovement_", "rl_bindings.h", [t|CInt -> CInt -> IO CFloat|], False), ("c'setGamepadMappings", "SetGamepadMappings_", "rl_bindings.h", [t|CString -> IO CInt|], False),+ ("c'setGamepadVibration", "SetGamepadVibration_", "rl_bindings.h", [t|CInt -> CFloat -> CFloat -> IO ()|], False), ("c'isMouseButtonPressed", "IsMouseButtonPressed_", "rl_bindings.h", [t|CInt -> IO CBool|], False), ("c'isMouseButtonDown", "IsMouseButtonDown_", "rl_bindings.h", [t|CInt -> IO CBool|], False), ("c'isMouseButtonReleased", "IsMouseButtonReleased_", "rl_bindings.h", [t|CInt -> IO CBool|], False),@@ -969,15 +975,15 @@ nativeSetShaderValue :: Shader -> Int -> ShaderUniformData -> IO () nativeSetShaderValue shader locIndex value = do- (uniformType, ptr) <- unpackShaderUniformData value- withFreeable shader (\s -> c'setShaderValue s (fromIntegral locIndex) ptr (fromIntegral $ fromEnum uniformType))- c'free $ castPtr ptr+ (uniformType, fptr) <- unpackShaderUniformData value+ withFreeable shader (\s -> withForeignPtr fptr (\ptr -> c'setShaderValue s (fromIntegral locIndex) ptr (fromIntegral $ fromEnum uniformType)))+ finalizeForeignPtr fptr nativeSetShaderValueV :: Shader -> Int -> ShaderUniformDataV -> IO () nativeSetShaderValueV shader locIndex values = do- (uniformType, ptr, l) <- unpackShaderUniformDataV values- withFreeable shader (\s -> c'setShaderValueV s (fromIntegral locIndex) ptr (fromIntegral $ fromEnum uniformType) (fromIntegral l))- c'free $ castPtr ptr+ (uniformType, fptr, l) <- unpackShaderUniformDataV values+ withFreeable shader (\s -> withForeignPtr fptr (\ptr -> c'setShaderValueV s (fromIntegral locIndex) ptr (fromIntegral $ fromEnum uniformType) (fromIntegral l)))+ finalizeForeignPtr fptr setShaderValueMatrix :: Shader -> Int -> Matrix -> IO () setShaderValueMatrix shader locIndex mat = withFreeable shader (\s -> withFreeable mat (c'setShaderValueMatrix s (fromIntegral locIndex)))@@ -992,11 +998,11 @@ unloadShader :: Shader -> WindowResources -> IO () unloadShader shader = unloadSingleShader (shader'id shader) -getMouseRay :: Vector2 -> Camera3D -> IO Ray-getMouseRay mousePosition camera = withFreeable mousePosition (withFreeable camera . c'getMouseRay) >>= pop+getScreenToWorldRay :: Vector2 -> Camera3D -> IO Ray+getScreenToWorldRay position camera = withFreeable position (withFreeable camera . c'getScreenToWorldRay) >>= pop -getViewRay :: Vector2 -> Camera3D -> Float -> Float -> IO Ray-getViewRay mousePosition camera width height = withFreeable mousePosition (\p -> withFreeable camera (\c -> c'getViewRay p c (realToFrac width) (realToFrac height))) >>= pop+getScreenToWorldRayEx :: Vector2 -> Camera3D -> Float -> Float -> IO Ray+getScreenToWorldRayEx position camera width height = withFreeable position (\p -> withFreeable camera (\c -> c'getScreenToWorldRayEx p c (realToFrac width) (realToFrac height))) >>= pop getCameraMatrix :: Camera3D -> IO Matrix getCameraMatrix camera = withFreeable camera c'getCameraMatrix >>= pop@@ -1158,7 +1164,11 @@ isFileDropped = toBool <$> c'isFileDropped loadDroppedFiles :: IO FilePathList-loadDroppedFiles = c'loadDroppedFiles >>= pop+loadDroppedFiles = do+ ptr <- c'loadDroppedFiles+ val <- peek ptr+ c'unloadDroppedFiles ptr+ return val getFileModTime :: String -> IO Integer getFileModTime fileName = fromIntegral <$> withCString fileName c'getFileModTime@@ -1311,6 +1321,9 @@ setGamepadMappings :: String -> IO Int setGamepadMappings mappings = fromIntegral <$> withCString mappings c'setGamepadMappings++setGamepadVibration :: Int -> Float -> Float -> IO ()+setGamepadVibration gamepad leftMotor rightMotor = c'setGamepadVibration (fromIntegral gamepad) (realToFrac leftMotor) (realToFrac rightMotor) isMouseButtonPressed :: MouseButton -> IO Bool isMouseButtonPressed button = toBool <$> c'isMouseButtonPressed (fromIntegral $ fromEnum button)
src/Raylib/Core/Models.hs view
@@ -149,12 +149,12 @@ c'getRayCollisionBox, c'getRayCollisionMesh, c'getRayCollisionTriangle,- c'getRayCollisionQuad+ c'getRayCollisionQuad, ) where import Control.Monad (forM_)-import Foreign (Ptr, Storable (peek, poke), castPtr, fromBool, malloc, peekArray, toBool)+import Foreign (Ptr, Storable (peek), fromBool, peekArray, toBool, with) import Foreign.C ( CBool (..), CFloat (..),@@ -165,8 +165,7 @@ import GHC.IO (unsafePerformIO) import Raylib.Internal (WindowResources, addShaderId, addTextureId, addVaoId, addVboIds, unloadSingleShader, unloadSingleTexture, unloadSingleVaoId, unloadSingleVboIdList) import Raylib.Internal.Foreign- ( c'free,- pop,+ ( pop, popCArray, withFreeable, withFreeableArray,@@ -192,7 +191,6 @@ Vector2, Vector3, )-import Prelude hiding (length) $( genNative [ ("c'drawLine3D", "DrawLine3D_", "rl_bindings.h", [t|Ptr Vector3 -> Ptr Vector3 -> Ptr Color -> IO ()|], False),@@ -287,13 +285,13 @@ drawTriangleStrip3D points pointCount color = withFreeableArray points (\p -> withFreeable color (c'drawTriangleStrip3D p (fromIntegral pointCount))) drawCube :: Vector3 -> Float -> Float -> Float -> Color -> IO ()-drawCube position width height length color = withFreeable position (\p -> withFreeable color (c'drawCube p (realToFrac width) (realToFrac height) (realToFrac length)))+drawCube position width height _length color = withFreeable position (\p -> withFreeable color (c'drawCube p (realToFrac width) (realToFrac height) (realToFrac _length))) drawCubeV :: Vector3 -> Vector3 -> Color -> IO () drawCubeV position size color = withFreeable position (\p -> withFreeable size (withFreeable color . c'drawCubeV p)) drawCubeWires :: Vector3 -> Float -> Float -> Float -> Color -> IO ()-drawCubeWires position width height length color = withFreeable position (\p -> withFreeable color (c'drawCubeWires p (realToFrac width) (realToFrac height) (realToFrac length)))+drawCubeWires position width height _length color = withFreeable position (\p -> withFreeable color (c'drawCubeWires p (realToFrac width) (realToFrac height) (realToFrac _length))) drawCubeWiresV :: Vector3 -> Vector3 -> Color -> IO () drawCubeWiresV position size color = withFreeable position (\p -> withFreeable size (withFreeable color . c'drawCubeWiresV p))@@ -343,10 +341,7 @@ loadModelFromMesh :: Mesh -> WindowResources -> IO Model loadModelFromMesh mesh wr = do- meshPtr <- malloc- poke meshPtr mesh- model <- c'loadModelFromMesh meshPtr >>= pop- c'free $ castPtr meshPtr+ model <- with mesh c'loadModelFromMesh >>= pop storeMaterialData (model'materials model) wr return model @@ -434,10 +429,10 @@ genMeshPoly sides radius wr = c'genMeshPoly (fromIntegral sides) (realToFrac radius) >>= pop >>= (`storeMeshData` wr) genMeshPlane :: Float -> Float -> Int -> Int -> WindowResources -> IO Mesh-genMeshPlane width length resX resZ wr = c'genMeshPlane (realToFrac width) (realToFrac length) (fromIntegral resX) (fromIntegral resZ) >>= pop >>= (`storeMeshData` wr)+genMeshPlane width _length resX resZ wr = c'genMeshPlane (realToFrac width) (realToFrac _length) (fromIntegral resX) (fromIntegral resZ) >>= pop >>= (`storeMeshData` wr) genMeshCube :: Float -> Float -> Float -> WindowResources -> IO Mesh-genMeshCube width height length wr = c'genMeshCube (realToFrac width) (realToFrac height) (realToFrac length) >>= pop >>= (`storeMeshData` wr)+genMeshCube width height _length wr = c'genMeshCube (realToFrac width) (realToFrac height) (realToFrac _length) >>= pop >>= (`storeMeshData` wr) genMeshSphere :: Float -> Int -> Int -> WindowResources -> IO Mesh genMeshSphere radius rings slices wr = c'genMeshSphere (realToFrac radius) (fromIntegral rings) (fromIntegral slices) >>= pop >>= (`storeMeshData` wr)
src/Raylib/Core/Textures.hs view
@@ -25,7 +25,6 @@ genImagePerlinNoise, genImageCellular, genImageText,- imageCopy, imageFromImage, imageText, imageTextEx,@@ -213,7 +212,7 @@ c'colorAlphaBlend, c'getColor, c'getPixelColor,- c'setPixelColor+ c'setPixelColor, ) where @@ -485,9 +484,6 @@ genImageText width height text = withCString text (c'genImageText (fromIntegral width) (fromIntegral height)) >>= pop -imageCopy :: Image -> IO Image-imageCopy image = withFreeable image c'imageCopy >>= pop- imageFromImage :: Image -> Rectangle -> IO Image imageFromImage image rect = withFreeable image (withFreeable rect . c'imageFromImage) >>= pop @@ -698,11 +694,11 @@ unloadSingleTexture (texture'id $ renderTexture'texture renderTexture) wr unloadSingleFrameBuffer (renderTexture'id renderTexture) wr -updateTexture :: Texture -> Ptr () -> IO Texture-updateTexture texture pixels = withFreeable texture (\t -> c'updateTexture t pixels >> peek t)+updateTexture :: Texture -> Ptr () -> IO ()+updateTexture texture pixels = withFreeable texture (\t -> c'updateTexture t pixels) -updateTextureRec :: Texture -> Rectangle -> Ptr () -> IO Texture-updateTextureRec texture rect pixels = withFreeable texture (\t -> withFreeable rect (\r -> c'updateTextureRec t r pixels) >> peek t)+updateTextureRec :: Texture -> Rectangle -> Ptr () -> IO ()+updateTextureRec texture rect pixels = withFreeable texture (\t -> withFreeable rect (\r -> c'updateTextureRec t r pixels)) genTextureMipmaps :: Texture -> IO Texture genTextureMipmaps texture = withFreeable texture (\t -> c'genTextureMipmaps t >> peek t)
src/Raylib/Internal/Foreign.hs view
@@ -2,16 +2,14 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleInstances #-} -{-|-Miscellaneous utility functions for marshalling values to/from C. The most-notable thing in this module is the `Freeable` typeclass.--}+-- |+-- Miscellaneous utility functions for marshalling values to/from C. The most+-- notable thing in this module is the `Freeable` typeclass. module Raylib.Internal.Foreign ( c'free, p'free, freeMaybePtr, Freeable (..),- rlFreeArray, rlFreeMaybeArray, pop, popCArray,@@ -40,13 +38,13 @@ import Control.Monad (forM_, unless) import Data.Bits ((.|.))-import Foreign (FunPtr, Ptr, Storable (peek, peekByteOff, poke, pokeByteOff, sizeOf), castPtr, malloc, newArray, nullPtr, peekArray, plusPtr, with, callocBytes)-import Foreign.C (CFloat, CInt, CString, CUChar, CUInt, peekCString, withCString)-import Foreign.C.Types (CBool, CChar, CShort, CUShort)-import qualified Data.Text as T-import qualified Data.Text.Encoding as TE import qualified Data.ByteString as BS import Data.Maybe (fromMaybe)+import qualified Data.Text as T+import qualified Data.Text.Encoding as TE+import Foreign (FunPtr, Ptr, Storable (peek, peekByteOff, poke, sizeOf), allocaBytes, castPtr, malloc, newArray, nullPtr, peekArray, plusPtr, pokeArray0, with, withArray, withArrayLen)+import Foreign.C (CFloat, CInt, CString, CUChar, CUInt, peekCString, withCString)+import Foreign.C.Types (CBool, CChar, CShort, CUShort) -- Internal utility functions @@ -113,12 +111,9 @@ let val = arr !! i in rlFreeDependents val (plusPtr ptr (i * sizeOf val)) ) -rlFreeArray :: (Freeable a, Storable a) => [a] -> Ptr a -> IO ()-rlFreeArray arr ptr = rlFree arr (castPtr ptr)- rlFreeMaybeArray :: (Freeable a, Storable a) => Maybe [a] -> Ptr a -> IO () rlFreeMaybeArray Nothing _ = return ()-rlFreeMaybeArray (Just arr) ptr = rlFreeArray arr ptr+rlFreeMaybeArray (Just arr) ptr = rlFree arr (castPtr ptr) pop :: (Freeable a, Storable a) => Ptr a -> IO a pop ptr = do@@ -140,32 +135,40 @@ withFreeable :: (Freeable a, Storable a) => a -> (Ptr a -> IO b) -> IO b withFreeable val f = do- ptr <- malloc- poke ptr val- result <- f ptr- rlFree val ptr- return result+ with+ val+ ( \ptr -> do+ result <- f ptr+ rlFreeDependents val ptr+ return result+ ) withFreeableArray :: (Freeable a, Storable a) => [a] -> (Ptr a -> IO b) -> IO b withFreeableArray arr f = do- ptr <- newArray arr- result <- f ptr- rlFreeArray arr ptr- return result+ withArray+ arr+ ( \ptr -> do+ result <- f ptr+ rlFreeDependents arr (castPtr ptr)+ return result+ ) withFreeableArrayLen :: (Freeable a, Storable a) => [a] -> (Int -> Ptr a -> IO b) -> IO b withFreeableArrayLen arr f = do- ptr <- newArray arr- result <- f (length arr) ptr- rlFreeArray arr ptr- return result+ withArrayLen+ arr+ ( \l ptr -> do+ result <- f l ptr+ rlFreeDependents arr (castPtr ptr)+ return result+ ) withFreeableArray2D :: (Freeable a, Storable a) => [[a]] -> (Ptr (Ptr a) -> IO b) -> IO b withFreeableArray2D arr func = do arrays <- mapM newArray arr ptr <- newArray arrays res <- func ptr- forM_ (zip [0 ..] arrays) (\(i, a) -> rlFreeArray (arr !! i) a)+ forM_ (zip [0 ..] arrays) (\(i, a) -> rlFree (arr !! i) (castPtr a)) c'free $ castPtr ptr return res @@ -188,12 +191,14 @@ withCStringBuffer str bufferSize f = do let bytes = BS.unpack (TE.encodeUtf8 (T.pack str)) bufferSize' = fromMaybe (length bytes + 8) bufferSize- buffer <- callocBytes bufferSize'- mapM_ (uncurry (pokeByteOff buffer)) (zip [0 ..] bytes)- res <- f bufferSize' buffer- str' <- peekCString buffer- c'free $ castPtr buffer- return (res, str')+ allocaBytes+ bufferSize'+ ( \buffer -> do+ pokeArray0 0 buffer (map fromIntegral bytes)+ res <- f bufferSize' buffer+ str' <- peekCString buffer+ return (res, str')+ ) peekMaybe :: (Storable a) => Ptr (Ptr a) -> IO (Maybe a) peekMaybe ptr = do
src/Raylib/Types/Core.hs view
@@ -109,9 +109,11 @@ Storable (alignment, peek, poke, sizeOf), Word8, castPtr,+ mallocArray, newArray, peekArray,- plusPtr, callocArray, pokeArray,+ plusPtr,+ pokeArray, ) import Foreign.C ( CFloat,@@ -1050,7 +1052,7 @@ p'vrStereoConfig'scaleIn = (`plusPtr` 296) data FilePathList = FilePathList- { filePathlist'capacity :: Integer,+ { filePathList'capacity :: Integer, filePathList'paths :: [String] } deriving (Eq, Show)@@ -1137,7 +1139,7 @@ poke _p (AutomationEventList capacity events) = do poke (p'automationEventList'capacity _p) (fromIntegral capacity) poke (p'automationEventList'count _p) (fromIntegral (length events))- eventsPtr <- callocArray (fromIntegral capacity)+ eventsPtr <- mallocArray (fromIntegral capacity) pokeArray eventsPtr events poke (p'automationEventList'events _p) eventsPtr return ()
src/Raylib/Types/Core/Models.hs view
@@ -82,17 +82,21 @@ import Control.Monad (forM_, unless) import Foreign- ( Ptr,+ ( ForeignPtr,+ Ptr, Storable (alignment, peek, poke, sizeOf), Word16, Word8,+ castForeignPtr, castPtr, fromBool,- malloc,+ mallocForeignPtr,+ mallocForeignPtrArray, newArray, newForeignPtr, peekArray, plusPtr,+ pokeArray, toBool, withForeignPtr, )@@ -108,7 +112,7 @@ peekCString, ) import Raylib.Internal (c'rlGetShaderIdDefault)-import Raylib.Internal.Foreign (Freeable (rlFreeDependents), c'free, freeMaybePtr, newMaybeArray, p'free, peekMaybeArray, peekStaticArray, pokeStaticArray, rightPad, rlFreeArray, rlFreeMaybeArray)+import Raylib.Internal.Foreign (Freeable (rlFreeDependents), c'free, freeMaybePtr, newMaybeArray, p'free, peekMaybeArray, peekStaticArray, pokeStaticArray, rightPad, rlFree, rlFreeMaybeArray) import Raylib.Types.Core (Color, Matrix, Quaternion, Vector2 (Vector2), Vector3 (Vector3), Vector4 (Vector4)) import Raylib.Types.Core.Textures (Texture (texture'id)) @@ -196,89 +200,104 @@ deriving (Eq, Show) -- | Internal use-unpackShaderUniformData :: ShaderUniformData -> IO (ShaderUniformDataType, Ptr ())+unpackShaderUniformData :: ShaderUniformData -> IO (ShaderUniformDataType, ForeignPtr ()) unpackShaderUniformData u = do case u of (ShaderUniformFloat f) -> do- ptr <- malloc- poke ptr (realToFrac f :: CFloat)- return (ShaderUniformFloatType, castPtr ptr)+ fptr <- mallocForeignPtr+ withForeignPtr fptr (\ptr -> poke ptr (realToFrac f :: CFloat))+ return (ShaderUniformFloatType, castForeignPtr fptr) (ShaderUniformVec2 (Vector2 x y)) -> do- ptr <- newArray (map realToFrac [x, y] :: [CFloat])- return (ShaderUniformVec2Type, castPtr ptr)+ fptr <- mallocForeignPtrArray 2+ withForeignPtr fptr (\ptr -> pokeArray ptr (map realToFrac [x, y] :: [CFloat]))+ return (ShaderUniformVec2Type, castForeignPtr fptr) (ShaderUniformVec3 (Vector3 x y z)) -> do- ptr <- newArray (map realToFrac [x, y, z] :: [CFloat])- return (ShaderUniformVec3Type, castPtr ptr)+ fptr <- mallocForeignPtrArray 3+ withForeignPtr fptr (\ptr -> pokeArray ptr (map realToFrac [x, y, z] :: [CFloat]))+ return (ShaderUniformVec3Type, castForeignPtr fptr) (ShaderUniformVec4 (Vector4 x y z w)) -> do- ptr <- newArray (map realToFrac [x, y, z, w] :: [CFloat])- return (ShaderUniformVec4Type, castPtr ptr)+ fptr <- mallocForeignPtrArray 3+ withForeignPtr fptr (\ptr -> pokeArray ptr (map realToFrac [x, y, z, w] :: [CFloat]))+ return (ShaderUniformVec4Type, castForeignPtr fptr) (ShaderUniformInt i) -> do- ptr <- malloc- poke ptr (fromIntegral i :: CInt)- return (ShaderUniformIntType, castPtr ptr)+ fptr <- mallocForeignPtr+ withForeignPtr fptr (\ptr -> poke ptr (fromIntegral i :: CInt))+ return (ShaderUniformIntType, castForeignPtr fptr) (ShaderUniformIVec2 (i1, i2)) -> do- ptr <- newArray (map fromIntegral [i1, i2] :: [CInt])- return (ShaderUniformIVec2Type, castPtr ptr)+ fptr <- mallocForeignPtrArray 2+ withForeignPtr fptr (\ptr -> pokeArray ptr (map fromIntegral [i1, i2] :: [CInt]))+ return (ShaderUniformIVec2Type, castForeignPtr fptr) (ShaderUniformIVec3 (i1, i2, i3)) -> do- ptr <- newArray (map fromIntegral [i1, i2, i3] :: [CInt])- return (ShaderUniformIVec3Type, castPtr ptr)+ fptr <- mallocForeignPtrArray 3+ withForeignPtr fptr (\ptr -> pokeArray ptr (map fromIntegral [i1, i2, i3] :: [CInt]))+ return (ShaderUniformIVec3Type, castForeignPtr fptr) (ShaderUniformIVec4 (i1, i2, i3, i4)) -> do- ptr <- newArray (map fromIntegral [i1, i2, i3, i4] :: [CInt])- return (ShaderUniformIVec4Type, castPtr ptr)+ fptr <- mallocForeignPtrArray 4+ withForeignPtr fptr (\ptr -> pokeArray ptr (map fromIntegral [i1, i2, i3, i4] :: [CInt]))+ return (ShaderUniformIVec4Type, castForeignPtr fptr) (ShaderUniformSampler2D texture) -> do- ptr <- malloc- poke ptr (fromIntegral $ texture'id texture :: CInt)- return (ShaderUniformSampler2DType, castPtr ptr)+ fptr <- mallocForeignPtr+ withForeignPtr fptr (\ptr -> poke ptr (fromIntegral $ texture'id texture :: CInt))+ return (ShaderUniformSampler2DType, castForeignPtr fptr) -- | Internal use-unpackShaderUniformDataV :: ShaderUniformDataV -> IO (ShaderUniformDataType, Ptr (), Int)+unpackShaderUniformDataV :: ShaderUniformDataV -> IO (ShaderUniformDataType, ForeignPtr (), Int) unpackShaderUniformDataV xs = do case xs of (ShaderUniformFloatV fs) -> do- ptr <- newArray (map realToFrac fs :: [CFloat])- return (ShaderUniformFloatType, castPtr ptr, length fs)+ fptr <- mallocForeignPtrArray (length fs)+ withForeignPtr fptr (\ptr -> pokeArray ptr (map realToFrac fs :: [CFloat]))+ return (ShaderUniformFloatType, castForeignPtr fptr, length fs) (ShaderUniformVec2V vs) -> do- ptr <- newArray (map realToFrac $ concatMap (\(Vector2 x y) -> [x, y]) vs :: [CFloat])- return (ShaderUniformVec2Type, castPtr ptr, length vs)+ fptr <- mallocForeignPtrArray (2 * length vs)+ withForeignPtr fptr (\ptr -> pokeArray ptr (map realToFrac $ concatMap (\(Vector2 x y) -> [x, y]) vs :: [CFloat]))+ return (ShaderUniformVec2Type, castForeignPtr fptr, length vs) (ShaderUniformVec3V vs) -> do- ptr <- newArray (map realToFrac $ concatMap (\(Vector3 x y z) -> [x, y, z]) vs :: [CFloat])- return (ShaderUniformVec3Type, castPtr ptr, length vs)+ fptr <- mallocForeignPtrArray (3 * length vs)+ withForeignPtr fptr (\ptr -> pokeArray ptr (map realToFrac $ concatMap (\(Vector3 x y z) -> [x, y, z]) vs :: [CFloat]))+ return (ShaderUniformVec3Type, castForeignPtr fptr, length vs) (ShaderUniformVec4V vs) -> do- ptr <- newArray (map realToFrac $ concatMap (\(Vector4 x y z w) -> [x, y, z, w]) vs :: [CFloat])- return (ShaderUniformVec4Type, castPtr ptr, length vs)+ fptr <- mallocForeignPtrArray (4 * length vs)+ withForeignPtr fptr (\ptr -> pokeArray ptr (map realToFrac $ concatMap (\(Vector4 x y z w) -> [x, y, z, w]) vs :: [CFloat]))+ return (ShaderUniformVec4Type, castForeignPtr fptr, length vs) (ShaderUniformIntV is) -> do- ptr <- newArray (map fromIntegral is :: [CInt])- return (ShaderUniformIntType, castPtr ptr, length is)+ fptr <- mallocForeignPtrArray (length is)+ withForeignPtr fptr (\ptr -> pokeArray ptr (map fromIntegral is :: [CInt]))+ return (ShaderUniformFloatType, castForeignPtr fptr, length is) (ShaderUniformIVec2V is) -> do- ptr <- newArray (map fromIntegral $ concatMap (\(x, y) -> [x, y]) is :: [CInt])- return (ShaderUniformIVec2Type, castPtr ptr, length is)+ fptr <- mallocForeignPtrArray (2 * length is)+ withForeignPtr fptr (\ptr -> pokeArray ptr (map fromIntegral $ concatMap (\(x, y) -> [x, y]) is :: [CInt]))+ return (ShaderUniformIVec2Type, castForeignPtr fptr, length is) (ShaderUniformIVec3V is) -> do- ptr <- newArray (map fromIntegral $ concatMap (\(x, y, z) -> [x, y, z]) is :: [CInt])- return (ShaderUniformIVec3Type, castPtr ptr, length is)+ fptr <- mallocForeignPtrArray (3 * length is)+ withForeignPtr fptr (\ptr -> pokeArray ptr (map fromIntegral $ concatMap (\(x, y, z) -> [x, y, z]) is :: [CInt]))+ return (ShaderUniformIVec3Type, castForeignPtr fptr, length is) (ShaderUniformIVec4V is) -> do- ptr <- newArray (map fromIntegral $ concatMap (\(x, y, z, w) -> [x, y, z, w]) is :: [CInt])- return (ShaderUniformIVec4Type, castPtr ptr, length is)+ fptr <- mallocForeignPtrArray (4 * length is)+ withForeignPtr fptr (\ptr -> pokeArray ptr (map fromIntegral $ concatMap (\(x, y, z, w) -> [x, y, z, w]) is :: [CInt]))+ return (ShaderUniformIVec4Type, castForeignPtr fptr, length is) (ShaderUniformSampler2DV textures) -> do- ptr <- newArray (map (fromIntegral . texture'id) textures :: [CInt])- return (ShaderUniformSampler2DType, castPtr ptr, length textures)+ fptr <- mallocForeignPtr+ withForeignPtr fptr (\ptr -> pokeArray ptr (map (fromIntegral . texture'id) textures :: [CInt]))+ return (ShaderUniformSampler2DType, castForeignPtr fptr, length textures) -- Unused data ShaderAttributeDataType@@ -667,8 +686,8 @@ instance Freeable Model where rlFreeDependents val ptr = do- rlFreeArray (model'meshes val) =<< peek (p'model'meshes ptr)- rlFreeArray (model'materials val) =<< peek (p'model'materials ptr)+ rlFree (model'meshes val) . castPtr =<< peek (p'model'meshes ptr)+ rlFree (model'materials val) . castPtr =<< peek (p'model'materials ptr) c'free . castPtr =<< peek (p'model'meshMaterial ptr) freeMaybePtr . castPtr =<< peek (p'model'bones ptr) freeMaybePtr . castPtr =<< peek (p'model'bindPose ptr)
src/Raylib/Types/Core/Text.hs view
@@ -35,7 +35,7 @@ import Foreign.C ( CInt (..), )-import Raylib.Internal.Foreign (Freeable (rlFreeDependents), c'free, rlFreeArray)+import Raylib.Internal.Foreign (Freeable (rlFreeDependents), c'free, rlFree) import Raylib.Types.Core (Rectangle) import Raylib.Types.Core.Textures (Image, Texture, p'image'data) @@ -147,4 +147,4 @@ instance Freeable Font where rlFreeDependents val ptr = do c'free . castPtr =<< peek (p'font'recs ptr)- rlFreeArray (font'glyphs val) =<< peek (p'font'glyphs ptr)+ rlFree (font'glyphs val) . castPtr =<< peek (p'font'glyphs ptr)
src/Raylib/Types/Util/GUI.hs view
@@ -865,9 +865,9 @@ | IconFolder | IconFile | IconSandTimer- | Icon220- | Icon221- | Icon222+ | IconWarning+ | IconHelpBox+ | IconInfoBox | Icon223 | Icon224 | Icon225@@ -1125,9 +1125,9 @@ IconFolder -> 217 IconFile -> 218 IconSandTimer -> 219- Icon220 -> 220- Icon221 -> 221- Icon222 -> 222+ IconWarning -> 220+ IconHelpBox -> 221+ IconInfoBox -> 222 Icon223 -> 223 Icon224 -> 224 Icon225 -> 225@@ -1382,9 +1382,9 @@ 217 -> IconFolder 218 -> IconFile 219 -> IconSandTimer- 220 -> Icon220- 221 -> Icon221- 222 -> Icon222+ 220 -> IconWarning+ 221 -> IconHelpBox+ 222 -> IconInfoBox 223 -> Icon223 224 -> Icon224 225 -> Icon225
src/Raylib/Types/Util/RLGL.hs view
@@ -62,7 +62,7 @@ CInt (..), CUInt, )-import Raylib.Internal.Foreign (Freeable (rlFreeDependents), c'free, peekStaticArray, pokeStaticArray, rlFreeArray)+import Raylib.Internal.Foreign (Freeable (rlFreeDependents), c'free, peekStaticArray, pokeStaticArray, rlFree) import Raylib.Types.Core (Color, Vector2, Vector3) ---------------------------------------@@ -963,5 +963,5 @@ instance Freeable RLRenderBatch where rlFreeDependents val ptr = do- rlFreeArray (rlRenderBatch'vertexBuffers val) =<< peek (p'rlRenderBatch'vertexBuffers ptr)+ rlFree (rlRenderBatch'vertexBuffers val) . castPtr =<< peek (p'rlRenderBatch'vertexBuffers ptr) c'free . castPtr =<< peek (p'rlRenderBatch'draws ptr)
src/Raylib/Util/Math.hs view
@@ -29,6 +29,7 @@ vector2Transform, vector2Reflect, vector2Rotate,+ vector2Refract, -- ** Vector3 math vector3CrossProduct,@@ -90,8 +91,8 @@ ) where -import Raylib.Types (Matrix (..), Quaternion, Vector2 (Vector2), Vector3 (Vector3), Vector4 (Vector4)) import Data.Foldable (foldl')+import Raylib.Types (Matrix (..), Quaternion, Vector2 (Vector2), Vector3 (Vector3), Vector4 (Vector4)) epsilon :: Float epsilon = 0.000001@@ -233,7 +234,7 @@ constant val = fromList $ repeat val -- | Sum of all vectors in a structure- vectorSum :: Foldable t => t a -> a+ vectorSum :: (Foldable t) => t a -> a vectorSum = foldl' (|+|) zero -- | Vector additive inverse@@ -345,7 +346,7 @@ -- | Angle created by the line between two 2D vectors (parameters must be normalized) vector2LineAngle :: Vector2 -> Vector2 -> Float-vector2LineAngle (Vector2 sx sy) (Vector2 ex ey) = - atan2 (ey - sy) (ex - sx)+vector2LineAngle (Vector2 sx sy) (Vector2 ex ey) = -atan2 (ey - sy) (ex - sx) -- | Transform a 2D vector by the given matrix vector2Transform :: Vector2 -> Matrix -> Vector2@@ -367,6 +368,22 @@ c = cos angle s = sin angle +-- | Compute the direction of a refracted ray+vector2Refract ::+ -- | Normalized direction of the incoming ray+ Vector2 ->+ -- | Normalized normal vector of the interface of two optical media+ Vector2 ->+ -- | Ratio of the refractive index of the medium from where the ray comes+ -- to the refractive index of the medium on the other side of the surface+ Float ->+ Vector2+vector2Refract (Vector2 vx vy) (Vector2 nx ny) r = if d >= 0 then Vector2 (r * vx - (r * dot + d') * nx) (r * vy - (r * dot + d') * ny) else Vector2 0 0+ where+ dot = vx * nx + vy * ny+ d = 1 - r * r * (1 - dot * dot)+ d' = sqrt d+ ------------------------------------------------ -- Vector3 math -------------------------------- ------------------------------------------------@@ -516,20 +533,20 @@ matViewProjInv = Matrix ((a11 * b11 - a12 * b10 + a13 * b09) * invDet)- ((- a01 * b11 + a02 * b10 - a03 * b09) * invDet)+ ((-a01 * b11 + a02 * b10 - a03 * b09) * invDet) ((a31 * b05 - a32 * b04 + a33 * b03) * invDet)- ((- a21 * b05 + a22 * b04 - a23 * b03) * invDet)- ((- a10 * b11 + a12 * b08 - a13 * b07) * invDet)+ ((-a21 * b05 + a22 * b04 - a23 * b03) * invDet)+ ((-a10 * b11 + a12 * b08 - a13 * b07) * invDet) ((a00 * b11 - a02 * b08 + a03 * b07) * invDet)- ((- a30 * b05 + a32 * b02 - a33 * b01) * invDet)+ ((-a30 * b05 + a32 * b02 - a33 * b01) * invDet) ((a20 * b05 - a22 * b02 + a23 * b01) * invDet) ((a10 * b10 - a11 * b08 + a13 * b06) * invDet)- ((- a00 * b10 + a01 * b08 - a03 * b06) * invDet)+ ((-a00 * b10 + a01 * b08 - a03 * b06) * invDet) ((a30 * b04 - a31 * b02 + a33 * b00) * invDet)- ((- a20 * b04 + a21 * b02 - a23 * b00) * invDet)- ((- a10 * b09 + a11 * b07 - a12 * b06) * invDet)+ ((-a20 * b04 + a21 * b02 - a23 * b00) * invDet)+ ((-a10 * b09 + a11 * b07 - a12 * b06) * invDet) ((a00 * b09 - a01 * b07 + a02 * b06) * invDet)- ((- a30 * b03 + a31 * b01 - a32 * b00) * invDet)+ ((-a30 * b03 + a31 * b01 - a32 * b00) * invDet) ((a20 * b03 - a21 * b01 + a22 * b00) * invDet) (Vector4 rx ry rz rw) = quaternionTransform (Vector4 x y z 1) matViewProjInv @@ -574,16 +591,29 @@ matrixDeterminant :: Matrix -> Float matrixDeterminant (Matrix a00 a10 a20 a30 a01 a11 a21 a31 a02 a12 a22 a32 a03 a13 a23 a33) =- a30 * a21 * a12 * a03 - a20 * a31 * a12 * a03 - a30 * a11 * a22 * a03 + a10 * a31 * a22 * a03- + a20 * a11 * a32 * a03 - a10 * a21 * a32 * a03 - a30 * a21 * a02 * a13+ a30 * a21 * a12 * a03+ - a20 * a31 * a12 * a03+ - a30 * a11 * a22 * a03+ + a10 * a31 * a22 * a03+ + a20 * a11 * a32 * a03+ - a10 * a21 * a32 * a03+ - a30 * a21 * a02 * a13 + a20 * a31 * a02 * a13- + a30 * a01 * a22 * a13 - a00 * a31 * a22 * a13 - a20 * a01 * a32 * a13+ + a30 * a01 * a22 * a13+ - a00 * a31 * a22 * a13+ - a20 * a01 * a32 * a13 + a00 * a21 * a32 * a13- + a30 * a11 * a02 * a23 - a10 * a31 * a02 * a23 - a30 * a01 * a12 * a23+ + a30 * a11 * a02 * a23+ - a10 * a31 * a02 * a23+ - a30 * a01 * a12 * a23 + a00 * a31 * a12 * a23- + a10 * a01 * a32 * a23 - a00 * a11 * a32 * a23 - a20 * a11 * a02 * a33+ + a10 * a01 * a32 * a23+ - a00 * a11 * a32 * a23+ - a20 * a11 * a02 * a33 + a10 * a21 * a02 * a33- + a20 * a01 * a12 * a33 - a00 * a21 * a12 * a33 - a10 * a01 * a22 * a33+ + a20 * a01 * a12 * a33+ - a00 * a21 * a12 * a33+ - a10 * a01 * a22 * a33 + a00 * a11 * a22 * a33 -- | Trace of a matrix (sum of the values along the diagonal)@@ -602,20 +632,20 @@ (Matrix a00 a10 a20 a30 a01 a11 a21 a31 a02 a12 a22 a32 a03 a13 a23 a33) = Matrix ((a11 * b11 - a12 * b10 + a13 * b09) * invDet)- ((- a10 * b11 + a12 * b08 - a13 * b07) * invDet)+ ((-a10 * b11 + a12 * b08 - a13 * b07) * invDet) ((a10 * b10 - a11 * b08 + a13 * b06) * invDet)- ((- a10 * b09 + a11 * b07 - a12 * b06) * invDet)- ((- a01 * b11 + a02 * b10 - a03 * b09) * invDet)+ ((-a10 * b09 + a11 * b07 - a12 * b06) * invDet)+ ((-a01 * b11 + a02 * b10 - a03 * b09) * invDet) ((a00 * b11 - a02 * b08 + a03 * b07) * invDet)- ((- a00 * b10 + a01 * b08 - a03 * b06) * invDet)+ ((-a00 * b10 + a01 * b08 - a03 * b06) * invDet) ((a00 * b09 - a01 * b07 + a02 * b06) * invDet) ((a31 * b05 - a32 * b04 + a33 * b03) * invDet)- ((- a30 * b05 + a32 * b02 - a33 * b01) * invDet)+ ((-a30 * b05 + a32 * b02 - a33 * b01) * invDet) ((a30 * b04 - a31 * b02 + a33 * b00) * invDet)- ((- a30 * b03 + a31 * b01 - a32 * b00) * invDet)- ((- a21 * b05 + a22 * b04 - a23 * b03) * invDet)+ ((-a30 * b03 + a31 * b01 - a32 * b00) * invDet)+ ((-a21 * b05 + a22 * b04 - a23 * b03) * invDet) ((a20 * b05 - a22 * b02 + a23 * b01) * invDet)- ((- a20 * b04 + a21 * b02 - a23 * b00) * invDet)+ ((-a20 * b04 + a21 * b02 - a23 * b00) * invDet) ((a20 * b03 - a21 * b01 + a22 * b00) * invDet) where b00 = a00 * a11 - a01 * a10@@ -706,39 +736,39 @@ -- | x-rotation matrix (angle should be in radians) matrixRotateX :: Float -> Matrix-matrixRotateX angle = Matrix 1 0 0 0 0 c (- s) 0 0 s c 0 0 0 0 1+matrixRotateX angle = Matrix 1 0 0 0 0 c (-s) 0 0 s c 0 0 0 0 1 where s = sin angle c = cos angle -- | y-rotation matrix (angle should be in radians) matrixRotateY :: Float -> Matrix-matrixRotateY angle = Matrix c 0 s 0 0 1 0 0 (- s) 0 c 0 0 0 0 1+matrixRotateY angle = Matrix c 0 s 0 0 1 0 0 (-s) 0 c 0 0 0 0 1 where s = sin angle c = cos angle -- | z-rotation matrix (angle should be in radians) matrixRotateZ :: Float -> Matrix-matrixRotateZ angle = Matrix c (- s) 0 0 s c 0 0 0 0 1 0 0 0 0 1+matrixRotateZ angle = Matrix c (-s) 0 0 s c 0 0 0 0 1 0 0 0 0 1 where s = sin angle c = cos angle -- | Euler angle xyz rotation matrix (angles should be in radians) matrixRotateXYZ :: Vector3 -> Matrix-matrixRotateXYZ (Vector3 x y z) = Matrix (cz - cy) (sz * cy) (- sy) 0 (cz * sy * sx - sz * cx) (sz * sy * sx + cz * cx) (cy * sx) 0 (cz * sy * cx + sz * sx) (sz * sy * cx - cz * sx) (cy * cx) 0 0 0 0 1+matrixRotateXYZ (Vector3 x y z) = Matrix (cz - cy) (sz * cy) (-sy) 0 (cz * sy * sx - sz * cx) (sz * sy * sx + cz * cx) (cy * sx) 0 (cz * sy * cx + sz * sx) (sz * sy * cx - cz * sx) (cy * cx) 0 0 0 0 1 where- cx = cos (- x)- sx = sin (- x)- cy = cos (- y)- sy = sin (- y)- cz = cos (- z)- sz = sin (- z)+ cx = cos (-x)+ sx = sin (-x)+ cy = cos (-y)+ sy = sin (-y)+ cz = cos (-z)+ sz = sin (-z) -- | Euler angle zyx rotation matrix (angles should be in radians) matrixRotateZYX :: Vector3 -> Matrix-matrixRotateZYX (Vector3 x y z) = Matrix (cz * cy) (cz * sy * sx - cx * sz) (sz * sx + cz * cx * sy) 0 (cy * sz) (cz * cx + sz * sy * sx) (cx * sz * sy - cz * sx) 0 (- sy) (cy * sx) (cy * cx) 0 0 0 0 1+matrixRotateZYX (Vector3 x y z) = Matrix (cz * cy) (cz * sy * sx - cx * sz) (sz * sx + cz * cx * sy) 0 (cy * sz) (cz * cx + sz * sy * sx) (cx * sz * sy - cz * sx) 0 (-sy) (cy * sx) (cy * cx) 0 0 0 0 1 where cz = cos z sz = sin z@@ -778,8 +808,8 @@ 0 0 0- (- (far + near) / z)- (- far * near * 2 / z)+ (-(far + near) / z)+ (-far * near * 2 / z) 0 0 (-1)@@ -803,9 +833,9 @@ matrixPerspective fovy aspect near far = matrixFrustum left right bottom top near far where top = near * tan (fovy / 2)- bottom = - top+ bottom = -top right = top * aspect- left = - right+ left = -right -- | Orthographic projection matrix matrixOrtho ::@@ -823,7 +853,7 @@ Float -> Matrix matrixOrtho left right bottom top near far =- Matrix (2 / x) 0 0 (- (left + right) / x) 0 (2 / y) 0 (- (top + bottom) / y) 0 0 (-2 / z) (- (far + near) / z) 0 0 0 1+ Matrix (2 / x) 0 0 (-(left + right) / x) 0 (2 / y) 0 (-(top + bottom) / y) 0 0 (-2 / z) (-(far + near) / z) 0 0 0 1 where x = right - left y = top - bottom@@ -838,7 +868,7 @@ -- | World up vector Vector3 -> Matrix-matrixLookAt eye target up = Matrix xx xy xz (- vx |.| eye) yx yy yz (- vy |.| eye) zx zy zz (- vz |.| eye) 0 0 0 1+matrixLookAt eye target up = Matrix xx xy xz (-vx |.| eye) yx yy yz (-vy |.| eye) zx zy zz (-vz |.| eye) 0 0 0 1 where vz@(Vector3 zx zy zz) = vectorNormalize $ eye |-| target vx@(Vector3 xx xy xz) = vectorNormalize $ vector3CrossProduct up vz@@ -854,7 +884,7 @@ -- | Invert a quaternion quaternionInvert :: Quaternion -> Quaternion-quaternionInvert q@(Vector4 x y z w) = Vector4 (- x * invLength) (- y * invLength) (- z * invLength) (w * invLength)+quaternionInvert q@(Vector4 x y z w) = Vector4 (-x * invLength) (-y * invLength) (-z * invLength) (w * invLength) where invLength = 1 / magnitudeSqr q @@ -903,7 +933,7 @@ | abs sinHalfTheta < epsilon = (q1 |+| q2') |/ 2 | otherwise = (q1 |* ratioA) |+| (q2 |* ratioB) where- cosHalfTheta = if dot < 0 then - dot else dot+ cosHalfTheta = if dot < 0 then -dot else dot sinHalfTheta = sqrt (1 - cosHalfTheta * cosHalfTheta) halfTheta = acos cosHalfTheta
src/Raylib/Util/RLGL.hs view
@@ -351,7 +351,7 @@ c'rlglClose, c'rlDrawRenderBatchActive, c'rlLoadDrawCube,- c'rlLoadDrawQuad+ c'rlLoadDrawQuad, ) where @@ -360,10 +360,12 @@ Storable (peek, poke, sizeOf), Word8, castPtr,+ finalizeForeignPtr, fromBool, malloc, nullPtr, toBool,+ withForeignPtr, ) import Foreign.C ( CBool (..),@@ -1162,8 +1164,9 @@ -- | Set shader value uniform rlSetUniform :: Int -> ShaderUniformDataV -> IO () rlSetUniform locIndex value = do- (dataType, ptr, count) <- unpackShaderUniformDataV value- c'rlSetUniform (fromIntegral locIndex) ptr (fromIntegral $ fromEnum dataType) (fromIntegral count)+ (dataType, fptr, count) <- unpackShaderUniformDataV value+ withForeignPtr fptr (\ptr -> c'rlSetUniform (fromIntegral locIndex) ptr (fromIntegral $ fromEnum dataType) (fromIntegral count))+ finalizeForeignPtr fptr -- | Set shader value matrix rlSetUniformMatrix :: Int -> Matrix -> IO ()