1/*
2 Copyright (C) Valve Corporation
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19*/
20#include "SDL_internal.h"
21
22
23#include "controller_type.h"
24#include "controller_list.h"
25
26
27static const char *GetControllerTypeOverride( int nVID, int nPID )
28{
29 const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERTYPE);
30 if (hint) {
31 char key[32];
32 const char *spot = NULL;
33
34 SDL_snprintf(key, sizeof(key), "0x%.4x/0x%.4x=", nVID, nPID);
35 spot = SDL_strstr(hint, key);
36 if (!spot) {
37 SDL_snprintf(key, sizeof(key), "0x%.4X/0x%.4X=", nVID, nPID);
38 spot = SDL_strstr(hint, key);
39 }
40 if (spot) {
41 spot += SDL_strlen(key);
42 if (SDL_strncmp(spot, "k_eControllerType_", 18) == 0) {
43 spot += 18;
44 }
45 return spot;
46 }
47 }
48 return NULL;
49}
50
51
52EControllerType GuessControllerType( int nVID, int nPID )
53{
54#if 0//def _DEBUG
55 // Verify that there are no duplicates in the controller list
56 // If the list were sorted, we could do this much more efficiently, as well as improve lookup speed.
57 static bool s_bCheckedForDuplicates;
58 if ( !s_bCheckedForDuplicates )
59 {
60 s_bCheckedForDuplicates = true;
61 int i, j;
62 for ( i = 0; i < sizeof( arrControllers ) / sizeof( arrControllers[ 0 ] ); ++i )
63 {
64 for ( j = i + 1; j < sizeof( arrControllers ) / sizeof( arrControllers[ 0 ] ); ++j )
65 {
66 if ( arrControllers[ i ].m_unDeviceID == arrControllers[ j ].m_unDeviceID )
67 {
68 Log( "Duplicate controller entry found for VID 0x%.4x PID 0x%.4x\n", ( arrControllers[ i ].m_unDeviceID >> 16 ), arrControllers[ i ].m_unDeviceID & 0xFFFF );
69 }
70 }
71 }
72 }
73#endif // _DEBUG
74
75 unsigned int unDeviceID = MAKE_CONTROLLER_ID( nVID, nPID );
76 int iIndex;
77
78 const char *pszOverride = GetControllerTypeOverride( nVID, nPID );
79 if ( pszOverride )
80 {
81 if ( SDL_strncasecmp( pszOverride, "Xbox360", 7 ) == 0 )
82 {
83 return k_eControllerType_XBox360Controller;
84 }
85 if ( SDL_strncasecmp( pszOverride, "XboxOne", 7 ) == 0 )
86 {
87 return k_eControllerType_XBoxOneController;
88 }
89 if ( SDL_strncasecmp( pszOverride, "PS3", 3 ) == 0 )
90 {
91 return k_eControllerType_PS3Controller;
92 }
93 if ( SDL_strncasecmp( pszOverride, "PS4", 3 ) == 0 )
94 {
95 return k_eControllerType_PS4Controller;
96 }
97 if ( SDL_strncasecmp( pszOverride, "PS5", 3 ) == 0 )
98 {
99 return k_eControllerType_PS5Controller;
100 }
101 if ( SDL_strncasecmp( pszOverride, "SwitchPro", 9 ) == 0 )
102 {
103 return k_eControllerType_SwitchProController;
104 }
105 if ( SDL_strncasecmp( pszOverride, "Steam", 5 ) == 0 )
106 {
107 return k_eControllerType_SteamController;
108 }
109 return k_eControllerType_UnknownNonSteamController;
110 }
111
112 for ( iIndex = 0; iIndex < sizeof( arrControllers ) / sizeof( arrControllers[0] ); ++iIndex )
113 {
114 if ( unDeviceID == arrControllers[ iIndex ].m_unDeviceID )
115 {
116 return arrControllers[ iIndex ].m_eControllerType;
117 }
118 }
119
120 return k_eControllerType_UnknownNonSteamController;
121
122}
123
124const char *GuessControllerName( int nVID, int nPID )
125{
126 unsigned int unDeviceID = MAKE_CONTROLLER_ID( nVID, nPID );
127 int iIndex;
128 for ( iIndex = 0; iIndex < sizeof( arrControllers ) / sizeof( arrControllers[0] ); ++iIndex )
129 {
130 if ( unDeviceID == arrControllers[ iIndex ].m_unDeviceID )
131 {
132 return arrControllers[ iIndex ].m_pszName;
133 }
134 }
135
136 return NULL;
137
138}
139
140#undef MAKE_CONTROLLER_ID
141