Port for macOS (#311)

* merged moonlight-mac with moonlight-ios

* reverted to the original project.pbxproj

* cleaned up the code, fixed lots of unnecessary code duplications

* multicontroller support (not tested)

* new class that can be used for further modularization of the MainFrameViewController
This commit is contained in:
Felix Kratz
2018-03-27 08:50:40 +02:00
committed by Cameron Gutman
parent 1c86c4485d
commit 6cc165b589
73 changed files with 5116 additions and 239 deletions

View File

@@ -7,7 +7,14 @@
//
#import "ControllerSupport.h"
#if TARGET_OS_IPHONE
#import "OnScreenControls.h"
#else
#import "Gamepad.h"
#import "Control.h"
#endif
#import "DataManager.h"
#include "Limelight.h"
@@ -21,17 +28,19 @@
NSLock *_controllerStreamLock;
NSMutableDictionary *_controllers;
#if TARGET_OS_IPHONE
OnScreenControls *_osc;
bool _oscEnabled;
// This controller object is shared between on-screen controls
// and player 0
Controller *_player0osc;
char _controllerNumbers;
#define EMULATING_SELECT 0x1
#define EMULATING_SPECIAL 0x2
#endif
bool _oscEnabled;
char _controllerNumbers;
}
// UPDATE_BUTTON_FLAG(controller, flag, pressed)
@@ -76,6 +85,7 @@
}
}
#if TARGET_OS_IPHONE
-(void) handleSpecialCombosReleased:(Controller*)controller releasedButtons:(int)releasedButtons
{
if ((controller.emulatingButtonFlags & EMULATING_SELECT) &&
@@ -110,21 +120,23 @@
}
}
#endif
-(void) updateButtonFlags:(Controller*)controller flags:(int)flags
{
@synchronized(controller) {
int releasedButtons = (controller.lastButtonFlags ^ flags) & ~flags;
int pressedButtons = (controller.lastButtonFlags ^ flags) & flags;
controller.lastButtonFlags = flags;
// This must be called before handleSpecialCombosPressed
// because we clear the original button flags there
#if TARGET_OS_IPHONE
int releasedButtons = (controller.lastButtonFlags ^ flags) & ~flags;
int pressedButtons = (controller.lastButtonFlags ^ flags) & flags;
[self handleSpecialCombosReleased:controller releasedButtons:releasedButtons];
[self handleSpecialCombosPressed:controller pressedButtons:pressedButtons];
#endif
}
}
@@ -132,7 +144,9 @@
{
@synchronized(controller) {
controller.lastButtonFlags |= flags;
#if TARGET_OS_IPHONE
[self handleSpecialCombosPressed:controller pressedButtons:flags];
#endif
}
}
@@ -140,7 +154,9 @@
{
@synchronized(controller) {
controller.lastButtonFlags &= ~flags;
#if TARGET_OS_IPHONE
[self handleSpecialCombosReleased:controller releasedButtons:flags];
#endif
}
}
@@ -242,6 +258,7 @@
}
}
#if TARGET_OS_IPHONE
-(void) updateAutoOnScreenControlMode
{
// Auto on-screen control support may not be enabled
@@ -277,6 +294,7 @@
[self updateAutoOnScreenControlMode];
}
#endif
-(void) assignController:(GCController*)controller {
for (int i = 0; i < 4; i++) {
@@ -285,6 +303,7 @@
controller.playerIndex = i;
Controller* limeController;
#if TARGET_OS_IPHONE
if (i == 0) {
// Player 0 shares a controller object with the on-screen controls
limeController = _player0osc;
@@ -292,6 +311,10 @@
limeController = [[Controller alloc] init];
limeController.playerIndex = i;
}
#else
limeController = [[Controller alloc] init];
limeController.playerIndex = i;
#endif
[_controllers setObject:limeController forKey:[NSNumber numberWithInteger:controller.playerIndex]];
@@ -301,9 +324,40 @@
}
}
#if TARGET_OS_IPHONE
-(Controller*) getOscController {
return _player0osc;
}
#else
-(NSMutableDictionary*) getControllers {
return _controllers;
}
-(void) assignGamepad:(struct Gamepad_device *)gamepad {
for (int i = 0; i < 4; i++) {
if (!(_controllerNumbers & (1 << i))) {
_controllerNumbers |= (1 << i);
gamepad->deviceID = i;
NSLog(@"Gamepad device id: %u assigned", gamepad->deviceID);
Controller* limeController;
limeController = [[Controller alloc] init];
limeController.playerIndex = i;
[_controllers setObject:limeController forKey:[NSNumber numberWithInteger:i]];
break;
}
}
}
-(void) removeGamepad:(struct Gamepad_device *)gamepad {
_controllerNumbers &= ~(1 << gamepad->deviceID);
Log(LOG_I, @"Unassigning controller index: %ld", (long)gamepad->deviceID);
// Inform the server of the updated active gamepads before removing this controller
[self updateFinished:[_controllers objectForKey:[NSNumber numberWithInteger:gamepad->deviceID]]];
[_controllers removeObjectForKey:[NSNumber numberWithInteger:gamepad->deviceID]];
}
#endif
+(int) getConnectedGamepadMask {
int mask = 0;
@@ -312,6 +366,7 @@
mask |= 1 << i;
}
#if TARGET_OS_IPHONE
DataManager* dataMan = [[DataManager alloc] init];
OnScreenControlsLevel level = (OnScreenControlsLevel)[[dataMan getSettings].onscreenControls integerValue];
@@ -320,7 +375,7 @@
if (level != OnScreenControlsLevelOff) {
mask |= 1;
}
#endif
return mask;
}
@@ -331,17 +386,27 @@
_controllerStreamLock = [[NSLock alloc] init];
_controllers = [[NSMutableDictionary alloc] init];
_controllerNumbers = 0;
#if TARGET_OS_IPHONE
_player0osc = [[Controller alloc] init];
_player0osc.playerIndex = 0;
DataManager* dataMan = [[DataManager alloc] init];
_oscEnabled = (OnScreenControlsLevel)[[dataMan getSettings].onscreenControls integerValue] != OnScreenControlsLevelOff;
#else
_oscEnabled = false;
initGamepad(self);
Gamepad_detectDevices();
#endif
Log(LOG_I, @"Number of controllers connected: %ld", (long)[[GCController controllers] count]);
for (GCController* controller in [GCController controllers]) {
[self assignController:controller];
[self registerControllerCallbacks:controller];
#if TARGET_OS_IPHONE
[self updateAutoOnScreenControlMode];
#endif
}
self.connectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
@@ -353,8 +418,10 @@
// Register callbacks on the new controller
[self registerControllerCallbacks:controller];
#if TARGET_OS_IPHONE
// Re-evaluate the on-screen control mode
[self updateAutoOnScreenControlMode];
#endif
}];
self.disconnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
Log(LOG_I, @"Controller disconnected!");
@@ -367,11 +434,12 @@
// Inform the server of the updated active gamepads before removing this controller
[self updateFinished:[_controllers objectForKey:[NSNumber numberWithInteger:controller.playerIndex]]];
[_controllers removeObjectForKey:[NSNumber numberWithInteger:controller.playerIndex]];
#if TARGET_OS_IPHONE
// Re-evaluate the on-screen control mode
[self updateAutoOnScreenControlMode];
#endif
}];
return self;
}