How can Mac OS X games accept low-level keyboard input events?

For games, low-level access to the keyboard input is required. Windows has DirectInput. But what technology do Mac OS X game developers use?

Obviously, there are enough Mac games that get keyboard input just to the right, without the disadvantages of well-known solutions:

Solution # 1: Use keyUp / keyDown events

-(void)keyUp:(NSEvent*)event; -(void)keyDown:(NSEvent*)event; 

Unacceptable disadvantage: keyDown events are repeated in accordance with the system settings for the "key repetition rate" and "key repetition delay." This triggers the keyDown event, followed by a pause before it starts to repeat at the speed specified by the system settings. This solution cannot be used for continuous key events.

I wonder if it's possible to disable key repetition behavior? I believe that you could read the first KeyDown key, and then remember the "key with keyCode x is down" state in your class until the keyUp event for that key is received, thereby avoiding the problems of delayed repetition and repetition.

Solution # 2: Use Event Briefs for Quarts Projects

See Quartz Event Services It seems quite low.

Unacceptable flaw: it is required that auxiliary devices be included in the system settings in the Universal Access - Keyboard section. Although this can be enabled by default, there is no guarantee that it can be disabled on some systems.

I also read that for short-term Quartz events, the application should be run as root, but no confirmation was found for this.

Solution # 3: Carbon Events / IOKit HID

The Carbon Event Manager Reference is deprecated and should not be used for new development.

Unacceptable flaw: no one knows how long Carbon events will be supported in future versions of Mac OS.

Besides being an outdated base, Carbon seems like the best solution. But are there any other disadvantages to using Carbon Events?

Questions:

What technology do game developers use for Mac OS X to receive input events with low keyboard levels? If they use one of the above technologies, how do they deal with the disadvantages that I mentioned?

UPDATE:

In the end, I switched to using regular NSEvent messages and wrapped them in a neat API for polling keyboard states .

+23
source share
6 answers

I got lucky with # 3, but it takes a lot of hard work if you want to support anything outside the keyboard.

One quick moment before we dive, although Carbon and IOKit HID are two different things. Carbon may go away at some point. But IOKit HID is here to stay, and just got a good facelift of 10.5.

For a complete example of how this all comes together, take a look at https://github.com/OpenEmu/OpenEmu/blob/master/OpenEmu/OEHIDManager.m . This is a small part of the puzzle, as there are other files.

The documentation of what you want to do can be found at http://developer.apple.com/library/mac/#documentation/DeviceDrivers/Conceptual/HID/new_api_10_5/tn2187.html

Again, this will not disappear anytime soon and is completely separate from Carbon and Carbon Events.

+9
source

I'm late for this party, but here is my solution for an OSX game that I write using Swift. It is very simple and seems to work very well.

First, you can put this code in a controller that receives keyboard events:

 var keysDown = Set<UInt16>() override func keyDown(e: NSEvent) { keysDown.insert(e.keyCode) } override func keyUp(e: NSEvent) { keysDown.remove(e.keyCode) } 

Then other parts of the system can determine if a particular key is omitted:

 if (keysDown.contains(49)) { // space bar is down } 

Or scroll through all the keys pressed

 for char in keysDown { switch char { case 49: // space player.jump() case 126: // up player.moveForward() case 124: // right player.turnRight() // ... etc ... default: // during development I have this line so I can easily see which keys have which codes print(char) } } 

Note keysDown is a Swift Set, so you don’t have to worry about duplication or ordering. The key is either in the set or not.

I'm not too sure how key codes are standardized. But you can offer a keyboard configuration page where the user can enter keys for each action, and then save any key code that it was.

+2
source

Okay, so I'm very late to the party, but I think mine is just straightforward and reminds me of Mr. Howard's decision above. Keep in mind that this input is used to control the camera in a SpriteKit game. Thus, you get smooth continuous movement and an exact stop.

 let moveRight: SKAction = SKAction.repeatForever(SKAction.moveBy(x: -5000, y: 0, duration: 1.5)) ... override func keyDown(with event: NSEvent) { camera!.constraints = [] // remove constraints usually added by a cameraComponent. let ekc = event.keyCode if ekc == 123 { camera!.run(moveLeft, withKey: "moveLeft") } if ekc == 124 { camera!.run(moveRight, withKey: "moveRight") } if ekc == 126 { camera!.run(moveUp, withKey: "moveUp") } if ekc == 125 { camera!.run(moveDown, withKey: "moveDown") } print("keyDown: \(event.characters!) keyCode: \(event.keyCode)") } override func keyUp(with event: NSEvent) { let ekc = event.keyCode if ekc == 123 { camera!.removeAction(forKey: "moveLeft") } if ekc == 124 { camera!.removeAction(forKey: "moveRight") } if ekc == 126 { camera!.removeAction(forKey: "moveUp") } if ekc == 125 { camera!.removeAction(forKey: "moveDown") } } 
+1
source
0
source

There are also some device classes in polkit (Obj-C toolkit), including ...

  • HIDController for using USB-HID devices
  • AppleRemote for using Apple Remote
  • MidiController for using Midi devices
  • OSCController to use OSC compatible devices over UDP
  • SerialPort use any serial port device
  • SC2004LCDModule for using SC 2004 from siliconcraft.net

http://code.google.com/p/polkit/

0
source

I found a very good example using Quartz event taps .

however the problems are:

  • for certain types of events, the user needs to run the application in root privileges. for example, root is required to capture keydown and keyup events.

  • interception is systemic, which means that when the program starts, it will capture all key events, even those that were sent to other applications. the implementation must be very careful not to disturb other applications.

0
source

Source: https://habr.com/ru/post/987451/


All Articles