diff options
Diffstat (limited to 'app')
| -rw-r--r-- | app/mac/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | app/mac/controller-adapter-gamepad.hh | 18 | ||||
| -rw-r--r-- | app/mac/controller-adapter-gamepad.mm | 32 | ||||
| -rw-r--r-- | app/mac/controller-adapter-keyboard.hh | 1 | ||||
| -rw-r--r-- | app/mac/controller-adapter.hh | 7 | ||||
| -rw-r--r-- | app/mac/scene.hh | 1 | ||||
| -rw-r--r-- | app/mac/scene.mm | 10 | ||||
| -rw-r--r-- | app/mac/view-controller.hh | 9 | ||||
| -rw-r--r-- | app/mac/view-controller.mm | 76 |
9 files changed, 140 insertions, 16 deletions
diff --git a/app/mac/CMakeLists.txt b/app/mac/CMakeLists.txt index d6ea464..e0d42d0 100644 --- a/app/mac/CMakeLists.txt +++ b/app/mac/CMakeLists.txt @@ -23,5 +23,7 @@ target_sources( view-controller.hh view-controller.mm controller-adapter.hh + controller-adapter-gamepad.hh + controller-adapter-gamepad.mm controller-adapter-keyboard.hh controller-adapter-keyboard.mm)
\ No newline at end of file diff --git a/app/mac/controller-adapter-gamepad.hh b/app/mac/controller-adapter-gamepad.hh index 14bfeae..c0caeed 100644 --- a/app/mac/controller-adapter-gamepad.hh +++ b/app/mac/controller-adapter-gamepad.hh @@ -1,16 +1,18 @@ -// -// Created by Hannes Schulze on 29.01.25. -// +#pragma once -#ifndef NES_CONTROLLER_ADAPTER_GAMEPAD_HH -#define NES_CONTROLLER_ADAPTER_GAMEPAD_HH +#import "controller-adapter.hh" +#import <GameController/GameController.h> +NS_ASSUME_NONNULL_BEGIN -class ControllerAdapterGamepad { +@interface ControllerAdapterGamepad : NSObject <ControllerAdapter> -}; +- (instancetype)initWithProfile:(GCExtendedGamepad*)profile; +- (instancetype)init NS_UNAVAILABLE; +@property (readonly) GCExtendedGamepad* profile; +@end -#endif //NES_CONTROLLER_ADAPTER_GAMEPAD_HH +NS_ASSUME_NONNULL_END
\ No newline at end of file diff --git a/app/mac/controller-adapter-gamepad.mm b/app/mac/controller-adapter-gamepad.mm index 132fa85..f1d8db8 100644 --- a/app/mac/controller-adapter-gamepad.mm +++ b/app/mac/controller-adapter-gamepad.mm @@ -1,5 +1,29 @@ -// -// Created by Hannes Schulze on 29.01.25. -// - #include "controller-adapter-gamepad.hh" + +@implementation ControllerAdapterGamepad + +- (instancetype)initWithProfile:(GCExtendedGamepad*)profile +{ + self = [super init]; + if (self) + { + _profile = profile; + } + return self; +} + +- (nes::button_mask)readPressedButtons +{ + auto res = nes::button_mask{}; + if ([[[_profile dpad] up] isPressed]) { res.add(nes::buttons::up); } + if ([[[_profile dpad] down] isPressed]) { res.add(nes::buttons::down); } + if ([[[_profile dpad] left] isPressed]) { res.add(nes::buttons::left); } + if ([[[_profile dpad] right] isPressed]) { res.add(nes::buttons::right); } + if ([[_profile buttonA] isPressed]) { res.add(nes::buttons::a); } + if ([[_profile buttonB] isPressed]) { res.add(nes::buttons::b); } + if ([[_profile leftTrigger] isPressed]) { res.add(nes::buttons::select); } + if ([[_profile rightTrigger] isPressed]) { res.add(nes::buttons::start); } + return res; +} + +@end
\ No newline at end of file diff --git a/app/mac/controller-adapter-keyboard.hh b/app/mac/controller-adapter-keyboard.hh index d91f069..7c3ef84 100644 --- a/app/mac/controller-adapter-keyboard.hh +++ b/app/mac/controller-adapter-keyboard.hh @@ -1,6 +1,7 @@ #pragma once #import "controller-adapter.hh" + #import <GameController/GameController.h> NS_ASSUME_NONNULL_BEGIN diff --git a/app/mac/controller-adapter.hh b/app/mac/controller-adapter.hh index d0fc33a..7a4c4b4 100644 --- a/app/mac/controller-adapter.hh +++ b/app/mac/controller-adapter.hh @@ -1,11 +1,16 @@ #pragma once #import "nes/util/button-mask.hh" + #import <Foundation/Foundation.h> +NS_ASSUME_NONNULL_BEGIN + /// Adapts inputs from a GCPhysicalInputProfile to a NES button mask. @protocol ControllerAdapter <NSObject> - (nes::button_mask)readPressedButtons; -@end
\ No newline at end of file +@end + +NS_ASSUME_NONNULL_END
\ No newline at end of file diff --git a/app/mac/scene.hh b/app/mac/scene.hh index ed56f2f..ba8eb31 100644 --- a/app/mac/scene.hh +++ b/app/mac/scene.hh @@ -1,6 +1,7 @@ #pragma once #import "controller-adapter.hh" + #import <SpriteKit/SpriteKit.h> NS_ASSUME_NONNULL_BEGIN diff --git a/app/mac/scene.mm b/app/mac/scene.mm index 0d50a7e..4ede6e0 100644 --- a/app/mac/scene.mm +++ b/app/mac/scene.mm @@ -97,6 +97,16 @@ namespace return self; } +- (void)keyUp:(NSEvent*)event +{ + // Handled by Game Controller +} + +- (void)keyDown:(NSEvent*)event +{ + // Handled by Game Controller +} + - (void)update:(NSTimeInterval)currentTime { _nes->ref_controller_1().set_pressed(_primaryController ? [_primaryController readPressedButtons] : nes::button_mask{}); diff --git a/app/mac/view-controller.hh b/app/mac/view-controller.hh index 4947b99..2eecd4e 100644 --- a/app/mac/view-controller.hh +++ b/app/mac/view-controller.hh @@ -3,15 +3,20 @@ #import <Cocoa/Cocoa.h> #import <GameController/GameController.h> +NS_ASSUME_NONNULL_BEGIN + @interface ViewController : GCEventViewController - (instancetype)initWithFilePath:(NSString*)filePath NS_DESIGNATED_INITIALIZER; -- (instancetype)initWithNibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil NS_UNAVAILABLE; +- (instancetype)initWithNibName:(nullable NSString*)nibNameOrNil + bundle:(nullable NSBundle*)nibBundleOrNil NS_UNAVAILABLE; - (instancetype)initWithCoder:(NSCoder*)coder NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE; @property (readonly) NSSize minimumDisplaySize; @property (readonly) NSSize preferredDisplaySize; -@end
\ No newline at end of file +@end + +NS_ASSUME_NONNULL_END
\ No newline at end of file diff --git a/app/mac/view-controller.mm b/app/mac/view-controller.mm index 8a1fcbd..eb81b6b 100644 --- a/app/mac/view-controller.mm +++ b/app/mac/view-controller.mm @@ -1,5 +1,6 @@ #import "view-controller.hh" #import "controller-adapter-keyboard.hh" +#import "controller-adapter-gamepad.hh" #import "scene.hh" @implementation ViewController @@ -7,6 +8,7 @@ Scene* _scene; NSSize _sceneSize; ControllerAdapterKeyboard* _keyboardController; + NSMutableArray<ControllerAdapterGamepad*>* _gamepadControllers; } - (instancetype)initWithFilePath:(NSString*)filePath @@ -18,11 +20,35 @@ _sceneSize = [_scene size]; _keyboardController = [[ControllerAdapterKeyboard alloc] init]; - [_scene setPrimaryController:_keyboardController]; + _gamepadControllers = [NSMutableArray array]; + for (GCController* controller in [GCController controllers]) + { + auto gamepad = [controller extendedGamepad]; + if (gamepad) + { + auto adapter = [[ControllerAdapterGamepad alloc] initWithProfile:gamepad]; + [_gamepadControllers addObject:adapter]; + } + } + [self updateControllers]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(handleControllerConnected:) + name:GCControllerDidConnectNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(handleControllerDisconnected:) + name:GCControllerDidDisconnectNotification + object:nil]; } return self; } +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + - (void)loadView { auto view = [[SKView alloc] init]; @@ -33,6 +59,54 @@ [self setView:view]; } +- (void)updateControllers +{ + // Prefer controllers, then fallback to keyboard input. + if ([_gamepadControllers count] >= 1) + { + [_scene setPrimaryController:[_gamepadControllers objectAtIndex:0]]; + if ([_gamepadControllers count] >= 2) + { + [_scene setSecondaryController:[_gamepadControllers objectAtIndex:1]]; + } + else + { + [_scene setSecondaryController:_keyboardController]; + } + } + else + { + [_scene setPrimaryController:_keyboardController]; + [_scene setSecondaryController:nil]; + } +} + +- (void)handleControllerConnected:(NSNotification*)notification +{ + auto controller = (GCController*)[notification object]; + auto gamepad = [controller extendedGamepad]; + if (gamepad) + { + auto adapter = [[ControllerAdapterGamepad alloc] initWithProfile:gamepad]; + [_gamepadControllers addObject:adapter]; + } + [self updateControllers]; +} + +- (void)handleControllerDisconnected:(NSNotification*)notification +{ + auto controller = (GCController*)[notification object]; + for (auto i = NSUInteger{ [_gamepadControllers count] }; i > 0; --i) + { + auto adapter = [_gamepadControllers objectAtIndex:(i - 1)]; + if ([[adapter profile] controller] == controller) + { + [_gamepadControllers removeObjectAtIndex:(i - 1)]; + } + } + [self updateControllers]; +} + - (NSSize)minimumDisplaySize { return _sceneSize; |
