1 module Dgame.System.GameController; 2 3 private: 4 5 import derelict.sdl2.sdl; 6 7 import Dgame.System.Joystick; 8 9 import Dgame.Internal.Error; 10 11 public: 12 13 /** 14 * Represent a Game Controller 15 * 16 * Author: Randy Schuett (rswhite4@googlemail.com) 17 */ 18 struct GameController { 19 private: 20 SDL_GameController* _controller; 21 22 public: 23 /** 24 * Supported Game Controller Axis 25 */ 26 enum Axis { 27 Invalid = SDL_CONTROLLER_AXIS_INVALID, /// 28 LeftX = SDL_CONTROLLER_AXIS_LEFTX, /// 29 LeftY = SDL_CONTROLLER_AXIS_LEFTY, /// 30 RightX = SDL_CONTROLLER_AXIS_RIGHTX, /// 31 RightY = SDL_CONTROLLER_AXIS_RIGHTY, /// 32 TriggerLeft = SDL_CONTROLLER_AXIS_TRIGGERLEFT, /// 33 TriggerRight = SDL_CONTROLLER_AXIS_TRIGGERRIGHT /// 34 } 35 36 /** 37 * Supported Game Controller Buttons 38 */ 39 enum Button { 40 Invalid = SDL_CONTROLLER_BUTTON_INVALID, /// 41 A = SDL_CONTROLLER_BUTTON_A, /// 42 B = SDL_CONTROLLER_BUTTON_B, /// 43 X = SDL_CONTROLLER_BUTTON_X, /// 44 Y = SDL_CONTROLLER_BUTTON_Y, /// 45 Back = SDL_CONTROLLER_BUTTON_BACK, /// 46 Guide = SDL_CONTROLLER_BUTTON_GUIDE, /// 47 Start = SDL_CONTROLLER_BUTTON_START, /// 48 LeftStick = SDL_CONTROLLER_BUTTON_LEFTSTICK, /// 49 RightStick = SDL_CONTROLLER_BUTTON_RIGHTSTICK, /// 50 LeftShoulder = SDL_CONTROLLER_BUTTON_LEFTSHOULDER, /// 51 RightShoulder = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, /// 52 DPadUp = SDL_CONTROLLER_BUTTON_DPAD_UP, /// 53 DPadDown = SDL_CONTROLLER_BUTTON_DPAD_DOWN, /// 54 DPadLeft = SDL_CONTROLLER_BUTTON_DPAD_LEFT, /// 55 DPadRight = SDL_CONTROLLER_BUTTON_DPAD_RIGHT /// 56 } 57 58 /** 59 * CTor 60 */ 61 @nogc 62 this(int device) nothrow { 63 _controller = SDL_GameControllerOpen(device); 64 if (!_controller) 65 print_fmt("Warning: Unable to open game controller %d! Error: %s\n", device, SDL_GetError()); 66 } 67 68 /** 69 * Postblit is disabled 70 */ 71 @disable 72 this(this); 73 74 /** 75 * DTor 76 */ 77 @nogc 78 ~this() nothrow { 79 if (_controller) 80 SDL_GameControllerClose(_controller); 81 } 82 83 /** 84 * Returns if the GameController has been opened and is currently connected. 85 */ 86 @nogc 87 bool isAttached() nothrow { 88 return SDL_GameControllerGetAttached(_controller) == SDL_TRUE; 89 } 90 91 /** 92 * Returns the value of the given Axis. 93 * The value is in range of short.min .. short.max 94 * 95 * See: Axis enum 96 */ 97 @nogc 98 short getAxisValue(Axis axis) nothrow { 99 return SDL_GameControllerGetAxis(_controller, axis); 100 } 101 102 /** 103 * Returns whether the given Button is pressed 104 */ 105 @nogc 106 bool isPressed(Button btn) nothrow { 107 return SDL_GameControllerGetButton(_controller, btn) == 1; 108 } 109 110 /** 111 * Returns the name of the GameController 112 */ 113 @nogc 114 string getName() nothrow { 115 import core.stdc..string : strlen; 116 117 const char* p = SDL_GameControllerName(_controller); 118 if (!p) 119 return null; 120 121 return cast(immutable) p[0 .. strlen(p)]; 122 } 123 124 /** 125 * Returns the mapping of the GameController 126 */ 127 @nogc 128 string getMapping() nothrow { 129 import core.stdc..string : strlen; 130 131 const char* p = SDL_GameControllerMapping(_controller); 132 if (!p) 133 return null; 134 135 return cast(immutable) p[0 .. strlen(p)]; 136 } 137 138 /** 139 * Returns the Joystick interface of the GameController 140 */ 141 @nogc 142 Joystick getJoystick() nothrow { 143 SDL_Joystick* joy = SDL_GameControllerGetJoystick(_controller); 144 145 return Joystick(joy); 146 } 147 148 /** 149 * Use this function to update the current state of the open GameController. 150 * This function is called automatically by the event loop 151 */ 152 @nogc 153 static void update() nothrow { 154 SDL_GameControllerUpdate(); 155 } 156 157 /** 158 * Returns the name of the GameController of the given device 159 */ 160 @nogc 161 static string getNameForIndex(int device) nothrow { 162 import core.stdc..string : strlen; 163 164 const char* p = SDL_GameControllerNameForIndex(device); 165 if (!p) 166 return null; 167 168 return cast(immutable) p[0 .. strlen(p)]; 169 } 170 171 /** 172 * Returns if the given device (e.g. a Joystick) is supported by the GameController interface. 173 * 174 * Note: Only if this method returns true, the device can be handled with the GameController struct 175 */ 176 @nogc 177 static bool isGameController(int device) nothrow { 178 return SDL_IsGameController(device) == SDL_TRUE; 179 } 180 }