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

@@ -0,0 +1,17 @@
//
// Control.h
// Moonlight macOS
//
// Created by Felix Kratz on 15.03.18.
// Copyright © 2018 Felix Kratz. All rights reserved.
//
#ifndef Control_h
#define Control_h
#include <stdio.h>
#import "ControllerSupport.h"
extern void initGamepad(ControllerSupport* controllerSupport);
#endif /* Control_h */

View File

@@ -0,0 +1,218 @@
//
// Control.m
// Moonlight macOS
//
// Created by Felix Kratz on 15.03.18.
// Copyright © 2018 Felix Kratz. All rights reserved.
//
#include "Gamepad.h"
#include "Control.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "Limelight.h"
#import "Moonlight-Swift.h"
@class Controller;
#ifdef _MSC_VER
#define snprintf _snprintf
#endif
Controller* _controller;
ControllerSupport* _controllerSupport;
NSMutableDictionary* _controllers;
typedef enum {
SELECT,
L3,
R3,
START,
UP,
RIGHT,
DOWN,
LEFT,
LB = 10,
RB,
Y,
B,
A,
X,
} ControllerKeys;
typedef enum {
LEFT_X,
LEFT_Y,
RIGHT_X,
RIGHT_Y,
LT = 14,
RT,
} ControllerAxis;
void onButtonDown(struct Gamepad_device * device, unsigned int buttonID, double timestamp, void * context) {
_controller = [_controllers objectForKey:[NSNumber numberWithInteger:device->deviceID]];
switch (buttonID) {
case SELECT:
[_controllerSupport setButtonFlag:_controller flags:BACK_FLAG];
break;
case L3:
[_controllerSupport setButtonFlag:_controller flags:LS_CLK_FLAG];
break;
case R3:
[_controllerSupport setButtonFlag:_controller flags:RS_CLK_FLAG];
break;
case START:
[_controllerSupport setButtonFlag:_controller flags:PLAY_FLAG];
break;
case UP:
[_controllerSupport setButtonFlag:_controller flags:UP_FLAG];
break;
case RIGHT:
[_controllerSupport setButtonFlag:_controller flags:RIGHT_FLAG];
break;
case DOWN:
[_controllerSupport setButtonFlag:_controller flags:DOWN_FLAG];
break;
case LEFT:
[_controllerSupport setButtonFlag:_controller flags:LEFT_FLAG];
break;
case LB:
[_controllerSupport setButtonFlag:_controller flags:LB_FLAG];
break;
case RB:
[_controllerSupport setButtonFlag:_controller flags:RB_FLAG];
break;
case Y:
[_controllerSupport setButtonFlag:_controller flags:Y_FLAG];
break;
case B:
[_controllerSupport setButtonFlag:_controller flags:B_FLAG];
break;
case A:
[_controllerSupport setButtonFlag:_controller flags:A_FLAG];
break;
case X:
[_controllerSupport setButtonFlag:_controller flags:X_FLAG];
break;
default:
break;
}
[_controllerSupport updateFinished:_controller];
}
void onButtonUp(struct Gamepad_device * device, unsigned int buttonID, double timestamp, void * context) {
_controller = [_controllers objectForKey:[NSNumber numberWithInteger:device->deviceID]];
switch (buttonID) {
case SELECT:
[_controllerSupport clearButtonFlag:_controller flags:BACK_FLAG];
break;
case L3:
[_controllerSupport clearButtonFlag:_controller flags:LS_CLK_FLAG];
break;
case R3:
[_controllerSupport clearButtonFlag:_controller flags:RS_CLK_FLAG];
break;
case START:
[_controllerSupport clearButtonFlag:_controller flags:PLAY_FLAG];
break;
case UP:
[_controllerSupport clearButtonFlag:_controller flags:UP_FLAG];
break;
case RIGHT:
[_controllerSupport clearButtonFlag:_controller flags:RIGHT_FLAG];
break;
case DOWN:
[_controllerSupport clearButtonFlag:_controller flags:DOWN_FLAG];
break;
case LEFT:
[_controllerSupport clearButtonFlag:_controller flags:LEFT_FLAG];
break;
case LB:
[_controllerSupport clearButtonFlag:_controller flags:LB_FLAG];
break;
case RB:
[_controllerSupport clearButtonFlag:_controller flags:RB_FLAG];
break;
case Y:
[_controllerSupport clearButtonFlag:_controller flags:Y_FLAG];
break;
case B:
[_controllerSupport clearButtonFlag:_controller flags:B_FLAG];
break;
case A:
[_controllerSupport clearButtonFlag:_controller flags:A_FLAG];
break;
case X:
[_controllerSupport clearButtonFlag:_controller flags:X_FLAG];
break;
default:
break;
}
[_controllerSupport updateFinished:_controller];
}
void onAxisMoved(struct Gamepad_device * device, unsigned int axisID, float value, float lastValue, double timestamp, void * context) {
if (fabsf(lastValue - value) > 0.01) {
_controller = [_controllers objectForKey:[NSNumber numberWithInteger:device->deviceID]];
// The dualshock controller has much more than these axis because of the motion axis, so it
// is better to call the updateFinished in the cases, because otherwise all of these
// motion axis will also trigger an updateFinished event.
switch (axisID) {
case LEFT_X:
_controller.lastLeftStickX = value * 0X7FFE;
[_controllerSupport updateFinished:_controller];
break;
case LEFT_Y:
_controller.lastLeftStickY = -value * 0X7FFE;
[_controllerSupport updateFinished:_controller];
break;
case RIGHT_X:
_controller.lastRightStickX = value * 0X7FFE;
[_controllerSupport updateFinished:_controller];
break;
case RIGHT_Y:
_controller.lastRightStickY = -value * 0X7FFE;
[_controllerSupport updateFinished:_controller];
break;
case LT:
_controller.lastLeftTrigger = value * 0xFF;
[_controllerSupport updateFinished:_controller];
break;
case RT:
_controller.lastRightTrigger = value * 0xFF;
[_controllerSupport updateFinished:_controller];
break;
default:
break;
}
}
}
void onDeviceAttached(struct Gamepad_device * device, void * context) {
[_controllerSupport assignGamepad:device];
_controllers = [_controllerSupport getControllers];
}
void onDeviceRemoved(struct Gamepad_device * device, void * context) {
[_controllerSupport removeGamepad:device];
_controllers = [_controllerSupport getControllers];
}
void initGamepad(ControllerSupport* controllerSupport) {
_controllerSupport = controllerSupport;
Gamepad_deviceAttachFunc(onDeviceAttached, NULL);
Gamepad_deviceRemoveFunc(onDeviceRemoved, NULL);
Gamepad_buttonDownFunc(onButtonDown, NULL);
Gamepad_buttonUpFunc(onButtonUp, NULL);
Gamepad_axisMoveFunc(onAxisMoved, NULL);
Gamepad_init();
_controller = [[Controller alloc] init];
}

View File

@@ -0,0 +1,4 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//

View File

@@ -0,0 +1,12 @@
//
// StreamView.h
// Moonlight macOS
//
// Created by Felix Kratz on 10.03.18.
// Copyright (c) 2018 Felix Kratz. All rights reserved.
//
@interface StreamView : NSView
@end

View File

@@ -0,0 +1,114 @@
//
// StreamView.m
// Moonlight macOS
//
// Created by Felix Kratz on 10.3.18.
// Copyright (c) 2018 Felix Kratz. All rights reserved.
//
#import "StreamView.h"
#include <Limelight.h>
#import "DataManager.h"
#include <ApplicationServices/ApplicationServices.h>
#include "keyboardTranslation.h"
@implementation StreamView {
BOOL isDragging;
NSTrackingArea *trackingArea;
}
- (void) updateTrackingAreas {
// This will be the area used to track the mouse movement
if (trackingArea != nil) {
[self removeTrackingArea:trackingArea];
}
NSTrackingAreaOptions options = (NSTrackingActiveAlways | NSTrackingInVisibleRect |
NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved);
trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
options:options
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
}
-(void)mouseDragged:(NSEvent *)event {
if (isDragging) {
[self mouseMoved:event];
}
else {
[self mouseDown:event];
isDragging = true;
}
}
-(void)rightMouseDragged:(NSEvent *)event {
if (isDragging) {
[self mouseMoved:event];
}
else {
[self rightMouseDown:event];
isDragging = true;
}
}
-(void)scrollWheel:(NSEvent *)event {
LiSendScrollEvent(event.scrollingDeltaY);
}
- (void)mouseDown:(NSEvent *)mouseEvent {
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
[self setNeedsDisplay:YES];
}
- (void)mouseUp:(NSEvent *)mouseEvent {
isDragging = false;
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
[self setNeedsDisplay:YES];
}
- (void)rightMouseUp:(NSEvent *)mouseEvent {
isDragging = false;
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_RIGHT);
[self setNeedsDisplay:YES];
}
- (void)rightMouseDown:(NSEvent *)mouseEvent {
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_RIGHT);
[self setNeedsDisplay:YES];
}
- (void)mouseMoved:(NSEvent *)mouseEvent {
LiSendMouseMoveEvent(mouseEvent.deltaX, mouseEvent.deltaY);
}
-(void)keyDown:(NSEvent *)event {
unsigned char keyChar = keyCharFromKeyCode(event.keyCode);
printf("DOWN: KeyCode: %hu, keyChar: %d, keyModifier: %lu \n", event.keyCode, keyChar, event.modifierFlags);
LiSendKeyboardEvent(keyChar, KEY_ACTION_DOWN, modifierFlagForKeyModifier(event.modifierFlags));
}
-(void)keyUp:(NSEvent *)event {
unsigned char keyChar = keyCharFromKeyCode(event.keyCode);
printf("UP: KeyChar: %d \n", keyChar);
LiSendKeyboardEvent(keyChar, KEY_ACTION_UP, modifierFlagForKeyModifier(event.modifierFlags));
}
- (void)flagsChanged:(NSEvent *)event
{
unsigned char keyChar = keyCodeFromModifierKey(event.modifierFlags);
if(keyChar) {
printf("DOWN: FlagChanged: %hhu \n", keyChar);
LiSendKeyboardEvent(keyChar, KEY_ACTION_DOWN, 0x00);
}
else {
LiSendKeyboardEvent(58, KEY_ACTION_UP, 0x00);
}
}
- (BOOL)acceptsFirstResponder {
return YES;
}
@end