input.go (11245B)
1 // Copyright 2015 Hajime Hoshi 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package ebiten 16 17 import ( 18 "github.com/hajimehoshi/ebiten/v2/internal/driver" 19 "github.com/hajimehoshi/ebiten/v2/internal/gamepaddb" 20 ) 21 22 // AppendInputChars appends "printable" runes, read from the keyboard at the time update is called, to runes, 23 // and returns the extended buffer. 24 // Giving a slice that already has enough capacity works efficiently. 25 // 26 // AppendInputChars represents the environment's locale-dependent translation of keyboard 27 // input to Unicode characters. 28 // 29 // IsKeyPressed is based on a mapping of device (US keyboard) codes to input device keys. 30 // "Control" and modifier keys should be handled with IsKeyPressed. 31 // 32 // AppendInputChars is concurrent-safe. 33 // 34 // On Android (ebitenmobile), EbitenView must be focusable to enable to handle keyboard keys. 35 // 36 // Keyboards don't work on iOS yet (#1090). 37 func AppendInputChars(runes []rune) []rune { 38 return uiDriver().Input().AppendInputChars(runes) 39 } 40 41 // InputChars return "printable" runes read from the keyboard at the time update is called. 42 // 43 // Deprecated: as of v2.2. Use AppendInputChars instead. 44 func InputChars() []rune { 45 return AppendInputChars(nil) 46 } 47 48 // IsKeyPressed returns a boolean indicating whether key is pressed. 49 // 50 // If you want to know whether the key started being pressed in the current frame, 51 // use inpututil.IsKeyJustPressed 52 // 53 // Known issue: On Edge browser, some keys don't work well: 54 // 55 // - KeyKPEnter and KeyKPEqual are recognized as KeyEnter and KeyEqual. 56 // - KeyPrintScreen is only treated at keyup event. 57 // 58 // IsKeyPressed is concurrent-safe. 59 // 60 // On Android (ebitenmobile), EbitenView must be focusable to enable to handle keyboard keys. 61 // 62 // Keyboards don't work on iOS yet (#1090). 63 func IsKeyPressed(key Key) bool { 64 if !key.isValid() { 65 return false 66 } 67 68 var keys []driver.Key 69 switch key { 70 case KeyAlt: 71 keys = []driver.Key{driver.KeyAltLeft, driver.KeyAltRight} 72 case KeyControl: 73 keys = []driver.Key{driver.KeyControlLeft, driver.KeyControlRight} 74 case KeyShift: 75 keys = []driver.Key{driver.KeyShiftLeft, driver.KeyShiftRight} 76 case KeyMeta: 77 keys = []driver.Key{driver.KeyMetaLeft, driver.KeyMetaRight} 78 default: 79 keys = []driver.Key{driver.Key(key)} 80 } 81 for _, k := range keys { 82 if uiDriver().Input().IsKeyPressed(k) { 83 return true 84 } 85 } 86 return false 87 } 88 89 // CursorPosition returns a position of a mouse cursor relative to the game screen (window). The cursor position is 90 // 'logical' position and this considers the scale of the screen. 91 // 92 // CursorPosition returns (0, 0) before the main loop on desktops and browsers. 93 // 94 // CursorPosition always returns (0, 0) on mobiles. 95 // 96 // CursorPosition is concurrent-safe. 97 func CursorPosition() (x, y int) { 98 return uiDriver().Input().CursorPosition() 99 } 100 101 // Wheel returns x and y offsets of the mouse wheel or touchpad scroll. 102 // It returns 0 if the wheel isn't being rolled. 103 // 104 // Wheel is concurrent-safe. 105 func Wheel() (xoff, yoff float64) { 106 return uiDriver().Input().Wheel() 107 } 108 109 // IsMouseButtonPressed returns a boolean indicating whether mouseButton is pressed. 110 // 111 // If you want to know whether the mouseButton started being pressed in the current frame, 112 // use inpututil.IsMouseButtonJustPressed 113 // 114 // IsMouseButtonPressed is concurrent-safe. 115 func IsMouseButtonPressed(mouseButton MouseButton) bool { 116 return uiDriver().Input().IsMouseButtonPressed(mouseButton) 117 } 118 119 // GamepadID represents a gamepad's identifier. 120 type GamepadID = driver.GamepadID 121 122 // GamepadSDLID returns a string with the GUID generated in the same way as SDL. 123 // To detect devices, see also the community project of gamepad devices database: https://github.com/gabomdq/SDL_GameControllerDB 124 // 125 // GamepadSDLID always returns an empty string on browsers and mobiles. 126 // 127 // GamepadSDLID is concurrent-safe. 128 func GamepadSDLID(id GamepadID) string { 129 return uiDriver().Input().GamepadSDLID(id) 130 } 131 132 // GamepadName returns a string with the name. 133 // This function may vary in how it returns descriptions for the same device across platforms. 134 // for example the following drivers/platforms see a Xbox One controller as the following: 135 // 136 // - Windows: "Xbox Controller" 137 // - Chrome: "Xbox 360 Controller (XInput STANDARD GAMEPAD)" 138 // - Firefox: "xinput" 139 // 140 // GamepadName always returns an empty string on iOS. 141 // 142 // GamepadName is concurrent-safe. 143 func GamepadName(id GamepadID) string { 144 return uiDriver().Input().GamepadName(id) 145 } 146 147 // AppendGamepadIDs appends available gamepad IDs to gamepadIDs, and returns the extended buffer. 148 // Giving a slice that already has enough capacity works efficiently. 149 // 150 // AppendGamepadIDs is concurrent-safe. 151 // 152 // AppendGamepadIDs doesn't append anything on iOS. 153 func AppendGamepadIDs(gamepadIDs []GamepadID) []GamepadID { 154 return uiDriver().Input().AppendGamepadIDs(gamepadIDs) 155 } 156 157 // GamepadIDs returns a slice indicating available gamepad IDs. 158 // 159 // Deprecated: as of v2.2. Use AppendGamepadIDs instead. 160 func GamepadIDs() []GamepadID { 161 return AppendGamepadIDs(nil) 162 } 163 164 // GamepadAxisNum returns the number of axes of the gamepad (id). 165 // 166 // GamepadAxisNum is concurrent-safe. 167 // 168 // GamepadAxisNum always returns 0 on iOS. 169 func GamepadAxisNum(id GamepadID) int { 170 return uiDriver().Input().GamepadAxisNum(id) 171 } 172 173 // GamepadAxisValue returns a float value [-1.0 - 1.0] of the given gamepad (id)'s axis (axis). 174 // 175 // GamepadAxisValue is concurrent-safe. 176 // 177 // GamepadAxisValue always returns 0 on iOS. 178 func GamepadAxisValue(id GamepadID, axis int) float64 { 179 return uiDriver().Input().GamepadAxisValue(id, axis) 180 } 181 182 // GamepadAxis returns a float value [-1.0 - 1.0] of the given gamepad (id)'s axis (axis). 183 // 184 // Deprecated: as of v2.2. Use GamepadAxisValue instead. 185 func GamepadAxis(id GamepadID, axis int) float64 { 186 return GamepadAxisValue(id, axis) 187 } 188 189 // GamepadButtonNum returns the number of the buttons of the given gamepad (id). 190 // 191 // GamepadButtonNum is concurrent-safe. 192 // 193 // GamepadButtonNum always returns 0 on iOS. 194 func GamepadButtonNum(id GamepadID) int { 195 return uiDriver().Input().GamepadButtonNum(id) 196 } 197 198 // IsGamepadButtonPressed reports whether the given button of the gamepad (id) is pressed or not. 199 // 200 // If you want to know whether the given button of gamepad (id) started being pressed in the current frame, 201 // use inpututil.IsGamepadButtonJustPressed 202 // 203 // IsGamepadButtonPressed is concurrent-safe. 204 // 205 // The relationships between physical buttons and buttion IDs depend on environments. 206 // There can be differences even between Chrome and Firefox. 207 // 208 // IsGamepadButtonPressed always returns false on iOS. 209 func IsGamepadButtonPressed(id GamepadID, button GamepadButton) bool { 210 return uiDriver().Input().IsGamepadButtonPressed(id, button) 211 } 212 213 // StandardGamepadAxisValue returns a float value [-1.0 - 1.0] of the given gamepad (id)'s standard axis (axis). 214 // 215 // StandardGamepadAxisValue returns 0 when the gamepad doesn't have a standard gamepad layout mapping. 216 // 217 // StandardGamepadAxisValue is concurrent safe. 218 func StandardGamepadAxisValue(id GamepadID, axis StandardGamepadAxis) float64 { 219 return uiDriver().Input().StandardGamepadAxisValue(id, axis) 220 } 221 222 // StandardGamepadButtonValue returns a float value [0.0 - 1.0] of the given gamepad (id)'s standard button (button). 223 // 224 // StandardGamepadButtonValue returns 0 when the gamepad doesn't have a standard gamepad layout mapping. 225 // 226 // StandardGamepadButtonValue is concurrent safe. 227 func StandardGamepadButtonValue(id GamepadID, button StandardGamepadButton) float64 { 228 return uiDriver().Input().StandardGamepadButtonValue(id, button) 229 } 230 231 // IsStandardGamepadButtonPressed reports whether the given gamepad (id)'s standard gamepad button (button) is pressed. 232 // 233 // IsStandardGamepadButtonPressed returns false when the gamepad doesn't have a standard gamepad layout mapping. 234 // 235 // IsStandardGamepadButtonPressed is concurrent safe. 236 func IsStandardGamepadButtonPressed(id GamepadID, button StandardGamepadButton) bool { 237 return uiDriver().Input().IsStandardGamepadButtonPressed(id, button) 238 } 239 240 // IsStandardGamepadLayoutAvailable reports whether the gamepad (id) has a standard gamepad layout mapping. 241 // 242 // IsStandardGamepadLayoutAvailable is concurrent-safe. 243 func IsStandardGamepadLayoutAvailable(id GamepadID) bool { 244 return uiDriver().Input().IsStandardGamepadLayoutAvailable(id) 245 } 246 247 // UpdateStandardGamepadLayoutMappings parses the specified string mappings in SDL_GameControllerDB format and 248 // updates the gamepad layout definitions. 249 // 250 // UpdateStandardGamepadLayoutMappings reports whether the mappings were applied, 251 // and returns an error in case any occurred while parsing the mappings. 252 // 253 // One or more input definitions can be provided separated by newlines. 254 // In particular, it is valid to pass an entire gamecontrollerdb.txt file. 255 // Note though that Ebiten already includes its own copy of this file, 256 // so this call should only be necessary to add mappings for hardware not supported yet; 257 // ideally games using the StandardGamepad* functions should allow the user to provide mappings and 258 // then call this function if provided. 259 // When using this facility to support new hardware, please also send a pull request to 260 // https://github.com/gabomdq/SDL_GameControllerDB to make your mapping available to everyone else. 261 // 262 // On platforms where gamepad mappings are not managed by Ebiten, this always returns false and nil. 263 // 264 // UpdateStandardGamepadLayoutMappings is concurrent-safe. 265 // 266 // Updated mappings take effect immediately even for already connected gamepads. 267 func UpdateStandardGamepadLayoutMappings(mappings string) (bool, error) { 268 return gamepaddb.Update([]byte(mappings)) 269 } 270 271 // TouchID represents a touch's identifier. 272 type TouchID = driver.TouchID 273 274 // AppendTouchIDs appends the current touch states to touches, and returns the extended buffer. 275 // Giving a slice that already has enough capacity works efficiently. 276 // 277 // If you want to know whether a touch started being pressed in the current frame, 278 // use inpututil.JustPressedTouchIDs 279 // 280 // AppendTouchIDs doesn't append anything when there are no touches. 281 // AppendTouchIDs always does nothing on desktops. 282 // 283 // AppendTouchIDs is concurrent-safe. 284 func AppendTouchIDs(touches []TouchID) []TouchID { 285 return uiDriver().Input().AppendTouchIDs(touches) 286 } 287 288 // TouchIDs returns the current touch states. 289 // 290 // Deperecated: as of v2.2. Use AppendTouchIDs instead. 291 func TouchIDs() []TouchID { 292 return AppendTouchIDs(nil) 293 } 294 295 // TouchPosition returns the position for the touch of the specified ID. 296 // 297 // If the touch of the specified ID is not present, TouchPosition returns (0, 0). 298 // 299 // TouchPosition is cuncurrent-safe. 300 func TouchPosition(id TouchID) (int, int) { 301 return uiDriver().Input().TouchPosition(id) 302 }