Skip to content

Commit 5eeb340

Browse files
authored
Gamepad audit (#27)
1 parent ecad7f0 commit 5eeb340

File tree

17 files changed

+479
-364
lines changed

17 files changed

+479
-364
lines changed

Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ let package = Package(
8686
.define("GATEENGINE_CLOSES_ALLWINDOWS_WITH_MAINWINDOW", .when(platforms: [.macOS, .windows, .linux])),
8787
/// Checks for reloadable resources and reloads them if they have changed
8888
.define("GATEENGINE_ENABLE_HOTRELOADING", .when(platforms: [.macOS, .windows, .linux], configuration: .debug)),
89-
/// THe host platfrom requests the main window, so GateEngine won't create one until it's requested
89+
/// The host platfrom requests the main window, so GateEngine won't create one until it's requested
9090
.define("GATEENGINE_PLATFORM_CREATES_MAINWINDOW", .when(platforms: [.iOS, .tvOS])),
9191
/// The host platform can't be usaed to compile HTML5 products
9292
.define("GATEENGINE_WASI_UNSUPPORTED_HOST", .when(platforms: [.windows])),
@@ -246,7 +246,7 @@ let package = Package(
246246
cxxSettings: openALCXXSettings,
247247
swiftSettings: {
248248
var array: [SwiftSetting] = []
249-
#if compiler(>=5.9)
249+
#if swift(>=5.9)
250250
array.append(.interoperabilityMode(.Cxx))
251251
#else
252252
array.append(.unsafeFlags(["-enable-experimental-cxx-interop", "-cxx-interoperability-mode=default"]))

README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@ A cross platform game engine for Swift that allows you to build 2D and 3D games.
33
Gate Engine includes intuitive APIs for loading resources, handling user inputs, and rendering content.
44

55
## Platform Support:
6-
| Platform | CI | Dependencies¹ | Render | Sound | Keyboard | Mouse | Touch | Gamepad |
7-
|---------:|:---|:--------------|:-------|:------|:----------|:-----|:------|:--------|
8-
| [**Windows**](https://www.swift.org/getting-started/#on-windows)² | [![](https://img.shields.io/github/actions/workflow/status/STREGAsGate/GateEngine/Windows.yml?label=)](https://github.com/STREGAsGate/GateEngine/actions/workflows/Windows.yml) | None | ✔︎ || ✔︎ | ✔︎ || `Buggy` |
9-
| [**macOS**](https://apps.apple.com/us/app/xcode/id497799835) | [![](https://img.shields.io/github/actions/workflow/status/STREGAsGate/GateEngine/macOS.yml?label=)](https://github.com/STREGAsGate/GateEngine/actions/workflows/macOS.yml) | None | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ |
10-
| [**Linux**](https://www.swift.org/getting-started/#on-linux) | [![](https://img.shields.io/github/actions/workflow/status/STREGAsGate/GateEngine/Linux.yml?label=)](https://github.com/STREGAsGate/GateEngine/actions/workflows/Linux.yml) | *TBD* | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ⛌ | ⛌
11-
| [**iOS**/**tvOS**](https://apps.apple.com/us/app/xcode/id497799835) | [![](https://img.shields.io/github/actions/workflow/status/STREGAsGate/GateEngine/iOS-tvOS.yml?label=)](https://github.com/STREGAsGate/GateEngine/actions/workflows/iOS-tvOS.yml) | None | ✔︎ | ✔︎ | ✔︎ | `iOS``tvOS` | ✔︎ | ✔︎
12-
| **Android** | [![](https://img.shields.io/github/actions/workflow/status/STREGAsGate/GateEngine/Android.yml?label=)](https://github.com/STREGAsGate/GateEngine/actions/workflows/Android.yml) | *TBD* | ⛌ | ⛌ | ⛌ | ⛌ | ⛌ | ⛌
13-
| [**HTML5**](https://book.swiftwasm.org/getting-started/setup.html) | [![](https://img.shields.io/github/actions/workflow/status/STREGAsGate/GateEngine/HTML5.yml?label=)](https://github.com/STREGAsGate/GateEngine/actions/workflows/HTML5.yml) | None | ✔︎| ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ |
6+
| Platform | CI | Render | Sound | Keyboard | Mouse | Touch | Gamepad |
7+
|---------:|:---|:-------|:------|:----------|:-----|:------|:--------|
8+
| [**Windows**](https://www.swift.org/getting-started/#on-windows)¹ | [![](https://img.shields.io/github/actions/workflow/status/STREGAsGate/GateEngine/Windows.yml?label=)](https://github.com/STREGAsGate/GateEngine/actions/workflows/Windows.yml) | ✔︎ || ✔︎ | ✔︎ || ✔︎ |
9+
| [**macOS**](https://apps.apple.com/us/app/xcode/id497799835) | [![](https://img.shields.io/github/actions/workflow/status/STREGAsGate/GateEngine/macOS.yml?label=)](https://github.com/STREGAsGate/GateEngine/actions/workflows/macOS.yml) | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ |
10+
| [**Linux**](https://www.swift.org/getting-started/#on-linux) | [![](https://img.shields.io/github/actions/workflow/status/STREGAsGate/GateEngine/Linux.yml?label=)](https://github.com/STREGAsGate/GateEngine/actions/workflows/Linux.yml) | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ⛌ | ⛌
11+
| [**iOS**/**tvOS**](https://apps.apple.com/us/app/xcode/id497799835) | [![](https://img.shields.io/github/actions/workflow/status/STREGAsGate/GateEngine/iOS-tvOS.yml?label=)](https://github.com/STREGAsGate/GateEngine/actions/workflows/iOS-tvOS.yml) | ✔︎ | ✔︎ | ✔︎ | ✔︎`iPad` | ✔︎ | ✔︎
12+
| **Android** | [![](https://img.shields.io/github/actions/workflow/status/STREGAsGate/GateEngine/Android.yml?label=)](https://github.com/STREGAsGate/GateEngine/actions/workflows/Android.yml) | ⛌ | ⛌ | ⛌ | ⛌ | ⛌ | ⛌
13+
| [**HTML5**](https://book.swiftwasm.org/getting-started/setup.html) | [![](https://img.shields.io/github/actions/workflow/status/STREGAsGate/GateEngine/HTML5.yml?label=)](https://github.com/STREGAsGate/GateEngine/actions/workflows/HTML5.yml) | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ |
1414

1515
Complete: ✔︎ | Incomplete: ⛌ | Partial: ◑
1616
<sub>
17-
</br>¹All platforms require a functioning Swift toolchain. Click a platform above for setup information.
18-
</br>²Windows support for Swift and Swift Package Manager is in development. Latest Swift toolchain recommended.
17+
</br>All platforms require a functioning Swift toolchain. Click a platform above for setup information.
18+
</br>¹Windows support for Swift and Swift Package Manager is in development. Latest Swift toolchain recommended.
1919
</sub>
2020

2121
## Getting Started

Sources/GateEngine/ECS/PlatformSystems/HIDSystem.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
*/
77

88
internal class HIDSystem: PlatformSystem {
9-
@inlinable
109
override func update(game: Game, input: HID, withTimePassed deltaTime: Float) async {
1110
input.update(deltaTime)
1211
}

Sources/GateEngine/GateEngine.swift

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ import GameMath
1313
import WinSDK
1414
#endif
1515

16+
#if canImport(WebAPIBase) && canImport(JavaScriptKit)
17+
import JavaScriptKit
18+
import WebAPIBase
19+
#endif
20+
1621
#if targetEnvironment(macCatalyst)
1722
#error("macCatalyst is not a supported platform.")
1823
#endif
@@ -98,10 +103,15 @@ internal enum Log {
98103
@_transparent @usableFromInline
99104
static func info(_ items: Any..., separator: String = " ", terminator: String = "\n") {
100105
let message = _message(prefix: "[GateEngine]", items, separator: separator)
106+
107+
#if os(WASI) || GATEENGINE_ENABLE_WASI_IDE_SUPPORT
108+
console.info(data: .string(message))
109+
#else
101110
Swift.print(message, terminator: terminator)
102111
#if os(Windows)
103112
WinSDK.OutputDebugStringW((message + terminator).windowsUTF16)
104113
#endif
114+
#endif
105115
}
106116

107117
@_transparent @usableFromInline
@@ -139,10 +149,16 @@ internal enum Log {
139149
}else{
140150
resolvedMessage = _message(prefix: "[GateEngine] warning:", items, separator: separator)
141151
}
142-
Swift.print(resolvedMessage, separator: separator, terminator: terminator)
152+
#if os(WASI) || GATEENGINE_ENABLE_WASI_IDE_SUPPORT
153+
console.warn(data: .string(resolvedMessage))
154+
#else
155+
143156
#if os(Windows)
144157
WinSDK.OutputDebugStringW((resolvedMessage + terminator).windowsUTF16)
145158
#endif
159+
160+
Swift.print(resolvedMessage, separator: separator, terminator: terminator)
161+
#endif
146162
}
147163

148164
@_transparent @usableFromInline
@@ -162,10 +178,16 @@ internal enum Log {
162178
}else{
163179
resolvedMessage = self._message(prefix: "[GateEngine] error:", items, separator: separator)
164180
}
165-
Swift.print(resolvedMessage, separator: separator, terminator: terminator)
181+
#if os(WASI) || GATEENGINE_ENABLE_WASI_IDE_SUPPORT
182+
console.error(data: .string(resolvedMessage))
183+
#else
184+
166185
#if canImport(WinSDK)
167186
WinSDK.OutputDebugStringW((resolvedMessage + terminator).windowsUTF16)
168187
#endif
188+
189+
Swift.print(resolvedMessage, separator: separator, terminator: terminator)
190+
#endif
169191
}
170192

171193
@_transparent @usableFromInline
@@ -181,17 +203,23 @@ internal enum Log {
181203
static func assert(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String, file: StaticString = #file, line: UInt = #line) {
182204
#if DEBUG
183205
let condition = condition()
184-
guard condition else {return}
206+
guard condition == false else {return}
185207

186208
let resolvedMessage: String
187209
if supportsColor {
188210
resolvedMessage = self._message(prefix: "[GateEngine] \(ANSIColors.red)error\(ANSIColors.default):", message(), separator: " ")
189211
}else{
190212
resolvedMessage = self._message(prefix: "[GateEngine] error:", message(), separator: " ")
191213
}
214+
192215
#if canImport(WinSDK)
193216
WinSDK.OutputDebugStringW((resolvedMessage + "/n").windowsUTF16)
194217
#endif
218+
219+
#if os(WASI) || GATEENGINE_ENABLE_WASI_IDE_SUPPORT
220+
console.assert(condition: condition, data: .string(resolvedMessage))
221+
#endif
222+
195223
Swift.assert(condition, resolvedMessage, file: file, line: line)
196224
#endif
197225
}
@@ -204,9 +232,15 @@ internal enum Log {
204232
}else{
205233
resolvedMessage = self._message(prefix: "[GateEngine] error:", message, separator: " ")
206234
}
235+
207236
#if canImport(WinSDK)
208237
WinSDK.OutputDebugStringW((resolvedMessage + "/n").windowsUTF16)
209238
#endif
239+
240+
#if os(WASI) || GATEENGINE_ENABLE_WASI_IDE_SUPPORT
241+
console.assert(condition: false, data: .string(resolvedMessage))
242+
#endif
243+
210244
return Swift.fatalError(resolvedMessage, file: file, line: line)
211245
}
212246
}

Sources/GateEngine/System/HID/GamePad/GamePad.swift

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public enum GamePadSymbolMap {
1515

1616
case microsoftXbox
1717

18-
/// The classic controller layouts are additive and include NES, SNES, GameBoy, GameBoy Advance
18+
/// The classic controller layouts are additive and include NES, SNES, GameBoy, GameBoy Advance, DS, 3DS
1919
case nintendoClassic
2020
case nintendoGameCube
2121
case nintendoSwitch
@@ -49,7 +49,24 @@ public struct GamePadSymbol: CustomStringConvertible {
4949
case .nintendoGameCube:
5050
fallthrough //TODO: Add GameCube nintenod symbols
5151
case .nintendoSwitch:
52-
fallthrough //TODO: Add Nintendo Switch symbols
52+
switch _id {
53+
case .leftStick: return .L
54+
case .leftStickButton: return .LSB
55+
case .rightStick: return .R
56+
case .rightStickButton: return .RSB
57+
case .south: return .B
58+
case .east: return .A
59+
case .west: return .Y
60+
case .north: return .X
61+
case .leftShoulder: return .L
62+
case .leftTrigger: return .ZL
63+
case .rightShoulder: return .R
64+
case .rightTrigger: return .ZR
65+
case .menu1: return .plus
66+
case .menu2: return .minus
67+
case .menu3: return .home
68+
default: return .unknown
69+
}
5370
case .unknown:
5471
fallthrough
5572
case .microsoftXbox:
@@ -308,7 +325,6 @@ public extension GamePad {
308325
self.interpreter = interpreter
309326
self.identifier = identifier
310327
self.interpreter.setupGamePad(self)
311-
self.interpreter.updateState(of: self)
312328
}
313329

314330
internal func resetInputStates() {
@@ -325,7 +341,7 @@ public extension GamePad {
325341
var _wrappedValue: T
326342
public var wrappedValue: T {
327343
get {
328-
Task(priority: .userInitiated) {
344+
Task(priority: .high) {
329345
gamePad?.interpreter.hid.gamePads.pollIfNeeded()
330346
}
331347
return _wrappedValue
@@ -385,8 +401,8 @@ public extension GamePad {
385401
maxHitCount += 1
386402
}
387403

388-
if minHitCount >= 5 && maxHitCount >= 5 {
389-
// if the input goes from min to max 5 times without an inbetween it is not analog
404+
if minHitCount >= 2 && maxHitCount >= 2 {
405+
// if the input goes from min to max 2 times without an inbetween it is not analog
390406
neverAnalog = true
391407
}
392408
}
@@ -406,14 +422,6 @@ public extension GamePad {
406422
let id: InternalID
407423
var currentRecipt: UInt8 = 0
408424

409-
init(gamePad: GamePad?, id: InternalID) {
410-
self.gamePad = gamePad
411-
self.id = id
412-
413-
self._isPressed.configureWith(gamePad: gamePad)
414-
self._value.configureWith(gamePad: gamePad, button: self)
415-
}
416-
417425
/// `true` if the button is considered down.
418426
@Polled public internal(set) var isPressed: Bool = false {
419427
didSet {
@@ -447,7 +455,7 @@ public extension GamePad {
447455

448456
/**
449457
Determines if this buttons `value` can have a value between 0 and 1
450-
This value will be initially false. The controller input has a few chances to report an analog value at which time this property become true, otherwise it's assumed to always be digital.
458+
This value will be initially false. The controller input has a few chances to report an analog value at which time this property will become true, otherwise it's assumed to always be digital.
451459
*/
452460
public internal(set) var isAnalog: Bool = false
453461

@@ -460,6 +468,14 @@ public extension GamePad {
460468
self.isPressed = false
461469
self.value = 0
462470
}
471+
472+
init(gamePad: GamePad?, id: InternalID) {
473+
self.gamePad = gamePad
474+
self.id = id
475+
476+
self._isPressed.configureWith(gamePad: gamePad)
477+
self._value.configureWith(gamePad: gamePad, button: self)
478+
}
463479
}
464480

465481
@MainActor public class StickState {

Sources/GateEngine/System/HID/GamePad/GamePadInterpreter/GamePadInterpreter.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,17 @@
66
*/
77

88
@MainActor internal protocol GamePadInterpreter {
9-
init(hid: HID)
109
var hid: HID {get}
1110
func beginInterpreting()
1211
func update()
1312
func endInterpreting()
1413
func setupGamePad(_ gamePad: GamePad)
1514
func updateState(of gamePad: GamePad)
1615
func description(of gamePad: GamePad) -> String
16+
var userReadableName: String {get}
17+
}
18+
19+
extension GamePadInterpreter {
20+
@_transparent
21+
var hid: HID {Game.shared.hid}
1722
}

0 commit comments

Comments
 (0)