@@ -15,18 +15,57 @@
|
|||||||
|
|
||||||
self.parent = settings;
|
self.parent = settings;
|
||||||
|
|
||||||
|
#if TARGET_OS_TV
|
||||||
|
NSInteger _bitrate = [[NSUserDefaults standardUserDefaults] integerForKey:@"bitrate"];
|
||||||
|
NSInteger _framerate = [[NSUserDefaults standardUserDefaults] integerForKey:@"framerate"];
|
||||||
|
|
||||||
|
if (_bitrate) {
|
||||||
|
self.bitrate = [NSNumber numberWithInteger:_bitrate];
|
||||||
|
} else {
|
||||||
|
self.bitrate = [NSNumber numberWithInteger:20000];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_framerate) {
|
||||||
|
self.framerate = [NSNumber numberWithInteger:_framerate];
|
||||||
|
} else {
|
||||||
|
self.framerate = [NSNumber numberWithInteger:60];
|
||||||
|
}
|
||||||
|
|
||||||
|
self.useHevc = [[NSUserDefaults standardUserDefaults] boolForKey:@"useHevc"] || NO;
|
||||||
|
self.playAudioOnPC = [[NSUserDefaults standardUserDefaults] boolForKey:@"audioOnPC"] || NO;
|
||||||
|
self.enableHdr = [[NSUserDefaults standardUserDefaults] boolForKey:@"enableHdr"] || NO;
|
||||||
|
self.optimizeGames = [[NSUserDefaults standardUserDefaults] boolForKey:@"optimizeGames"] || YES;
|
||||||
|
self.multiController = YES;
|
||||||
|
NSInteger _screenSize = [[NSUserDefaults standardUserDefaults] integerForKey:@"streamResolution"];
|
||||||
|
switch (_screenSize) {
|
||||||
|
case 0:
|
||||||
|
self.height = [NSNumber numberWithInteger:720];
|
||||||
|
self.width = [NSNumber numberWithInteger:1280];
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
self.height = [NSNumber numberWithInteger:2160];
|
||||||
|
self.width = [NSNumber numberWithInteger:3840];
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
default:
|
||||||
|
self.height = [NSNumber numberWithInteger:1080];
|
||||||
|
self.width = [NSNumber numberWithInteger:1920];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
self.bitrate = settings.bitrate;
|
self.bitrate = settings.bitrate;
|
||||||
self.framerate = settings.framerate;
|
self.framerate = settings.framerate;
|
||||||
self.height = settings.height;
|
self.height = settings.height;
|
||||||
self.width = settings.width;
|
self.width = settings.width;
|
||||||
self.onscreenControls = settings.onscreenControls;
|
|
||||||
self.uniqueId = settings.uniqueId;
|
|
||||||
self.streamingRemotely = settings.streamingRemotely;
|
|
||||||
self.useHevc = settings.useHevc;
|
self.useHevc = settings.useHevc;
|
||||||
self.multiController = settings.multiController;
|
|
||||||
self.playAudioOnPC = settings.playAudioOnPC;
|
self.playAudioOnPC = settings.playAudioOnPC;
|
||||||
self.enableHdr = settings.enableHdr;
|
self.enableHdr = settings.enableHdr;
|
||||||
self.optimizeGames = settings.optimizeGames;
|
self.optimizeGames = settings.optimizeGames;
|
||||||
|
self.multiController = settings.multiController;
|
||||||
|
#endif
|
||||||
|
self.onscreenControls = settings.onscreenControls;
|
||||||
|
self.uniqueId = settings.uniqueId;
|
||||||
|
self.streamingRemotely = settings.streamingRemotely;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,11 @@ static UIImage* noImage;
|
|||||||
noImage = [UIImage imageNamed:@"NoAppImage"];
|
noImage = [UIImage imageNamed:@"NoAppImage"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TARGET_OS_TV
|
||||||
|
_appButton = [UIButton buttonWithType:UIButtonTypeSystem];
|
||||||
|
#else
|
||||||
_appButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
_appButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||||
|
#endif
|
||||||
[_appButton setBackgroundImage:noImage forState:UIControlStateNormal];
|
[_appButton setBackgroundImage:noImage forState:UIControlStateNormal];
|
||||||
[_appButton setContentEdgeInsets:UIEdgeInsetsMake(0, 4, 0, 4)];
|
[_appButton setContentEdgeInsets:UIEdgeInsetsMake(0, 4, 0, 4)];
|
||||||
[_appButton sizeToFit];
|
[_appButton sizeToFit];
|
||||||
@@ -64,10 +68,12 @@ static UIImage* noImage;
|
|||||||
if ([_app.id isEqualToString:_app.host.currentGame]) {
|
if ([_app.id isEqualToString:_app.host.currentGame]) {
|
||||||
// Only create the app overlay if needed
|
// Only create the app overlay if needed
|
||||||
_appOverlay = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Play"]];
|
_appOverlay = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Play"]];
|
||||||
|
#if !TARGET_OS_TV
|
||||||
_appOverlay.layer.shadowColor = [UIColor blackColor].CGColor;
|
_appOverlay.layer.shadowColor = [UIColor blackColor].CGColor;
|
||||||
_appOverlay.layer.shadowOffset = CGSizeMake(0, 0);
|
_appOverlay.layer.shadowOffset = CGSizeMake(0, 0);
|
||||||
_appOverlay.layer.shadowOpacity = 1;
|
_appOverlay.layer.shadowOpacity = 1;
|
||||||
_appOverlay.layer.shadowRadius = 2.0;
|
_appOverlay.layer.shadowRadius = 2.0;
|
||||||
|
#endif
|
||||||
|
|
||||||
[self addSubview:_appOverlay];
|
[self addSubview:_appOverlay];
|
||||||
|
|
||||||
@@ -91,8 +97,20 @@ static UIImage* noImage;
|
|||||||
// TODO: Improve no-app image detection
|
// TODO: Improve no-app image detection
|
||||||
if (!(appImage.size.width == 130.f && appImage.size.height == 180.f) && // GFE 2.0
|
if (!(appImage.size.width == 130.f && appImage.size.height == 180.f) && // GFE 2.0
|
||||||
!(appImage.size.width == 628.f && appImage.size.height == 888.f)) { // GFE 3.0
|
!(appImage.size.width == 628.f && appImage.size.height == 888.f)) { // GFE 3.0
|
||||||
|
#if TARGET_OS_TV
|
||||||
|
//custom image to do TvOS hover popup effect
|
||||||
|
UIImageView *imageView = [[UIImageView alloc] initWithImage:appImage];
|
||||||
|
imageView.userInteractionEnabled = YES;
|
||||||
|
imageView.adjustsImageWhenAncestorFocused = YES;
|
||||||
|
imageView.frame = CGRectMake(0, 0, 200, 265);
|
||||||
|
[_appButton addSubview:imageView];
|
||||||
|
|
||||||
|
_appButton.frame = CGRectMake(0, 0, 200, 265);
|
||||||
|
self.frame = CGRectMake(0, 0, 200, 265);
|
||||||
|
#else
|
||||||
_appButton.frame = CGRectMake(0, 0, appImage.size.width / 2, appImage.size.height / 2);
|
_appButton.frame = CGRectMake(0, 0, appImage.size.width / 2, appImage.size.height / 2);
|
||||||
self.frame = CGRectMake(0, 0, appImage.size.width / 2, appImage.size.height / 2);
|
self.frame = CGRectMake(0, 0, appImage.size.width / 2, appImage.size.height / 2);
|
||||||
|
#endif
|
||||||
_appOverlay.frame = CGRectMake(0, 0, self.frame.size.width / 2.f, self.frame.size.height / 4.f);
|
_appOverlay.frame = CGRectMake(0, 0, self.frame.size.width / 2.f, self.frame.size.height / 4.f);
|
||||||
_appOverlay.layer.shadowRadius = 4.0;
|
_appOverlay.layer.shadowRadius = 4.0;
|
||||||
[_appOverlay setCenter:CGPointMake(self.frame.size.width/2, self.frame.size.height/6)];
|
[_appOverlay setCenter:CGPointMake(self.frame.size.width/2, self.frame.size.height/6)];
|
||||||
@@ -107,18 +125,35 @@ static UIImage* noImage;
|
|||||||
|
|
||||||
if (noAppImage) {
|
if (noAppImage) {
|
||||||
_appLabel = [[UILabel alloc] init];
|
_appLabel = [[UILabel alloc] init];
|
||||||
CGFloat padding = 4.f;
|
|
||||||
[_appLabel setFrame: CGRectMake(padding, padding, _appButton.frame.size.width - 2 * padding, _appButton.frame.size.height - 2 * padding)];
|
|
||||||
[_appLabel setTextColor:[UIColor whiteColor]];
|
[_appLabel setTextColor:[UIColor whiteColor]];
|
||||||
[_appLabel setBaselineAdjustment:UIBaselineAdjustmentAlignCenters];
|
[_appLabel setBaselineAdjustment:UIBaselineAdjustmentAlignCenters];
|
||||||
[_appLabel setTextAlignment:NSTextAlignmentCenter];
|
[_appLabel setTextAlignment:NSTextAlignmentCenter];
|
||||||
[_appLabel setLineBreakMode:NSLineBreakByWordWrapping];
|
[_appLabel setLineBreakMode:NSLineBreakByWordWrapping];
|
||||||
[_appLabel setNumberOfLines:0];
|
[_appLabel setNumberOfLines:0];
|
||||||
|
[_appLabel setText:_app.name];
|
||||||
#if TARGET_OS_TV
|
#if TARGET_OS_TV
|
||||||
[_appLabel setFont:[UIFont systemFontOfSize:16]];
|
[_appLabel setFont:[UIFont systemFontOfSize:16]];
|
||||||
#endif
|
[_appLabel setAdjustsFontSizeToFitWidth:YES];
|
||||||
[_appLabel setText:_app.name];
|
[_appLabel setFrame: CGRectMake(0, 0, 200, 265)];
|
||||||
|
//custom image to do TvOS hover popup effect
|
||||||
|
UIImageView *imageView = [[UIImageView alloc] initWithImage:appImage];
|
||||||
|
imageView.userInteractionEnabled = YES;
|
||||||
|
imageView.adjustsImageWhenAncestorFocused = YES;
|
||||||
|
imageView.frame = CGRectMake(0, 0, 200, 265);
|
||||||
|
UIGraphicsBeginImageContextWithOptions(_appLabel.frame.size, false, 0);
|
||||||
|
[imageView.layer renderInContext:(UIGraphicsGetCurrentContext())];
|
||||||
|
[_appLabel.layer renderInContext:(UIGraphicsGetCurrentContext())];
|
||||||
|
UIImage *imageWithText = UIGraphicsGetImageFromCurrentImageContext();
|
||||||
|
UIGraphicsEndImageContext();
|
||||||
|
[imageView setImage:imageWithText];
|
||||||
|
[_appButton addSubview:imageView];
|
||||||
|
_appButton.frame = CGRectMake(0, 0, 200, 265);
|
||||||
|
self.frame = CGRectMake(0, 0, 200, 265);
|
||||||
|
#else
|
||||||
|
CGFloat padding = 4.f;
|
||||||
|
[_appLabel setFrame: CGRectMake(padding, padding, _appButton.frame.size.width - 2 * padding, _appButton.frame.size.height - 2 * padding)];
|
||||||
[_appButton addSubview:_appLabel];
|
[_appButton addSubview:_appLabel];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,9 @@ static const int LABEL_DY = 20;
|
|||||||
|
|
||||||
[_hostLabel setText:@"Add Host"];
|
[_hostLabel setText:@"Add Host"];
|
||||||
[_hostLabel sizeToFit];
|
[_hostLabel sizeToFit];
|
||||||
|
#if !TARGET_OS_TV
|
||||||
_hostLabel.textColor = [UIColor whiteColor];
|
_hostLabel.textColor = [UIColor whiteColor];
|
||||||
|
#endif
|
||||||
_hostLabel.center = CGPointMake(_hostButton.frame.origin.x + (_hostButton.frame.size.width / 2), _hostButton.frame.origin.y + _hostButton.frame.size.height + LABEL_DY);
|
_hostLabel.center = CGPointMake(_hostButton.frame.origin.x + (_hostButton.frame.size.width / 2), _hostButton.frame.origin.y + _hostButton.frame.size.height + LABEL_DY);
|
||||||
|
|
||||||
UIImageView* addIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"AddComputerIcon"]];
|
UIImageView* addIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"AddComputerIcon"]];
|
||||||
@@ -128,7 +130,9 @@ static const int LABEL_DY = 20;
|
|||||||
|
|
||||||
- (void) updateContentsForHost:(TemporaryHost*)host {
|
- (void) updateContentsForHost:(TemporaryHost*)host {
|
||||||
_hostLabel.text = _host.name;
|
_hostLabel.text = _host.name;
|
||||||
|
#if !TARGET_OS_TV
|
||||||
_hostLabel.textColor = [UIColor whiteColor];
|
_hostLabel.textColor = [UIColor whiteColor];
|
||||||
|
#endif
|
||||||
[_hostLabel sizeToFit];
|
[_hostLabel sizeToFit];
|
||||||
|
|
||||||
switch (host.pairState) {
|
switch (host.pairState) {
|
||||||
@@ -142,7 +146,9 @@ static const int LABEL_DY = 20;
|
|||||||
_hostPairState.text = @"Paired";
|
_hostPairState.text = @"Paired";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#if !TARGET_OS_TV
|
||||||
_hostPairState.textColor = [UIColor whiteColor];
|
_hostPairState.textColor = [UIColor whiteColor];
|
||||||
|
#endif
|
||||||
[_hostPairState sizeToFit];
|
[_hostPairState sizeToFit];
|
||||||
|
|
||||||
if (host.online) {
|
if (host.online) {
|
||||||
|
|||||||
@@ -1001,9 +1001,8 @@ static NSMutableSet* hostList;
|
|||||||
cell.layer.shadowOpacity = 0.5f;
|
cell.layer.shadowOpacity = 0.5f;
|
||||||
cell.layer.shadowPath = shadowPath.CGPath;
|
cell.layer.shadowPath = shadowPath.CGPath;
|
||||||
|
|
||||||
cell.layer.borderWidth = 1;
|
|
||||||
|
|
||||||
#if !TARGET_OS_TV
|
#if !TARGET_OS_TV
|
||||||
|
cell.layer.borderWidth = 1;
|
||||||
cell.layer.borderColor = [[UIColor colorWithRed:0 green:0 blue:0 alpha:0.3f] CGColor];
|
cell.layer.borderColor = [[UIColor colorWithRed:0 green:0 blue:0 alpha:0.3f] CGColor];
|
||||||
cell.exclusiveTouch = YES;
|
cell.exclusiveTouch = YES;
|
||||||
#endif
|
#endif
|
||||||
@@ -1055,12 +1054,20 @@ static NSMutableSet* hostList;
|
|||||||
self.navigationController.navigationBar.topItem.rightBarButtonItem.enabled = YES;
|
self.navigationController.navigationBar.topItem.rightBarButtonItem.enabled = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TARGET_OS_TV
|
||||||
|
- (BOOL)canBecomeFocused {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
- (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator {
|
- (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator {
|
||||||
|
|
||||||
|
#if !TARGET_OS_TV
|
||||||
if (context.nextFocusedView != nil) {
|
if (context.nextFocusedView != nil) {
|
||||||
[context.nextFocusedView setAlpha:0.8];
|
[context.nextFocusedView setAlpha:0.8];
|
||||||
}
|
}
|
||||||
[context.previouslyFocusedView setAlpha:1.0];
|
[context.previouslyFocusedView setAlpha:1.0];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -12,7 +12,13 @@
|
|||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
#if TARGET_OS_TV
|
||||||
|
@import GameController;
|
||||||
|
|
||||||
|
@interface StreamFrameViewController : GCEventViewController <ConnectionCallbacks, EdgeDetectionDelegate>
|
||||||
|
#else
|
||||||
@interface StreamFrameViewController : UIViewController <ConnectionCallbacks, EdgeDetectionDelegate>
|
@interface StreamFrameViewController : UIViewController <ConnectionCallbacks, EdgeDetectionDelegate>
|
||||||
|
#endif
|
||||||
@property (strong, nonatomic) IBOutlet UILabel *stageLabel;
|
@property (strong, nonatomic) IBOutlet UILabel *stageLabel;
|
||||||
@property (strong, nonatomic) IBOutlet UIActivityIndicatorView *spinner;
|
@property (strong, nonatomic) IBOutlet UIActivityIndicatorView *spinner;
|
||||||
@property (nonatomic) StreamConfiguration* streamConfig;
|
@property (nonatomic) StreamConfiguration* streamConfig;
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
ControllerSupport *_controllerSupport;
|
ControllerSupport *_controllerSupport;
|
||||||
StreamManager *_streamMan;
|
StreamManager *_streamMan;
|
||||||
NSTimer *_inactivityTimer;
|
NSTimer *_inactivityTimer;
|
||||||
|
UITapGestureRecognizer *_menuGestureRecognizer;
|
||||||
|
UITapGestureRecognizer *_menuDoubleTapGestureRecognizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewDidAppear:(BOOL)animated
|
- (void)viewDidAppear:(BOOL)animated
|
||||||
@@ -31,6 +33,15 @@
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TARGET_OS_TV
|
||||||
|
- (void)controllerPauseButtonPressed:(id)sender { }
|
||||||
|
- (void)controllerPauseButtonDoublePressed:(id)sender {
|
||||||
|
Log(LOG_I, @"Menu double-pressed -- backing out of stream");
|
||||||
|
[self returnToMainFrame];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
- (void)viewDidLoad
|
- (void)viewDidLoad
|
||||||
{
|
{
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
@@ -46,6 +57,21 @@
|
|||||||
|
|
||||||
_controllerSupport = [[ControllerSupport alloc] initWithConfig:self.streamConfig];
|
_controllerSupport = [[ControllerSupport alloc] initWithConfig:self.streamConfig];
|
||||||
_inactivityTimer = nil;
|
_inactivityTimer = nil;
|
||||||
|
#if TARGET_OS_TV
|
||||||
|
if (!_menuGestureRecognizer || !_menuDoubleTapGestureRecognizer) {
|
||||||
|
_menuGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(controllerPauseButtonPressed:)];
|
||||||
|
_menuGestureRecognizer.allowedPressTypes = @[@(UIPressTypeMenu)];
|
||||||
|
|
||||||
|
_menuDoubleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(controllerPauseButtonDoublePressed:)];
|
||||||
|
_menuDoubleTapGestureRecognizer.numberOfTapsRequired = 2;
|
||||||
|
[_menuGestureRecognizer requireGestureRecognizerToFail:_menuDoubleTapGestureRecognizer];
|
||||||
|
_menuDoubleTapGestureRecognizer.allowedPressTypes = @[@(UIPressTypeMenu)];
|
||||||
|
}
|
||||||
|
|
||||||
|
[self.view addGestureRecognizer:_menuGestureRecognizer];
|
||||||
|
[self.view addGestureRecognizer:_menuDoubleTapGestureRecognizer];
|
||||||
|
#endif
|
||||||
|
|
||||||
_streamMan = [[StreamManager alloc] initWithConfig:self.streamConfig
|
_streamMan = [[StreamManager alloc] initWithConfig:self.streamConfig
|
||||||
renderView:self.view
|
renderView:self.view
|
||||||
connectionCallbacks:self];
|
connectionCallbacks:self];
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"idiom" : "tv"
|
"idiom" : "tv",
|
||||||
|
"filename" : "bg-app.jpg"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"info" : {
|
"info" : {
|
||||||
|
|||||||
|
After Width: | Height: | Size: 30 KiB |
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"idiom" : "tv"
|
"idiom" : "tv",
|
||||||
|
"filename" : "wedges-app.png"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"info" : {
|
"info" : {
|
||||||
|
|||||||
|
After Width: | Height: | Size: 75 KiB |
@@ -2,10 +2,12 @@
|
|||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"idiom" : "tv",
|
"idiom" : "tv",
|
||||||
|
"filename" : "bg.jpg",
|
||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "tv",
|
"idiom" : "tv",
|
||||||
|
"filename" : "bg@2.jpg",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 14 KiB |
@@ -2,10 +2,12 @@
|
|||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"idiom" : "tv",
|
"idiom" : "tv",
|
||||||
|
"filename" : "Wedges.png",
|
||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "tv",
|
"idiom" : "tv",
|
||||||
|
"filename" : "Wedges@2.png",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 39 KiB |
@@ -2,18 +2,22 @@
|
|||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"idiom" : "tv",
|
"idiom" : "tv",
|
||||||
|
"filename" : "topshelf-wide@1.png",
|
||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "tv",
|
"idiom" : "tv",
|
||||||
|
"filename" : "topshelf-wide@2.png",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "tv-marketing",
|
"idiom" : "tv-marketing",
|
||||||
|
"filename" : "topshelf-wide@1-1.png",
|
||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "tv-marketing",
|
"idiom" : "tv-marketing",
|
||||||
|
"filename" : "topshelf-wide@2-1.png",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
|
After Width: | Height: | Size: 398 KiB |
|
After Width: | Height: | Size: 398 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
@@ -2,18 +2,22 @@
|
|||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"idiom" : "tv",
|
"idiom" : "tv",
|
||||||
|
"filename" : "topshelf@1.png",
|
||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "tv",
|
"idiom" : "tv",
|
||||||
|
"filename" : "topshelf@2.png",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "tv-marketing",
|
"idiom" : "tv-marketing",
|
||||||
|
"filename" : "topshelf@1-1.png",
|
||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "tv-marketing",
|
"idiom" : "tv-marketing",
|
||||||
|
"filename" : "topshelf@2-1.png",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
|
After Width: | Height: | Size: 391 KiB |
|
After Width: | Height: | Size: 391 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
@@ -1,11 +1,11 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder.AppleTV.Storyboard" version="3.0" toolsVersion="14113" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="pui-7y-JNH">
|
<document type="com.apple.InterfaceBuilder.AppleTV.Storyboard" version="3.0" toolsVersion="14313.18" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="pui-7y-JNH">
|
||||||
<device id="appleTV" orientation="landscape">
|
<device id="appleTV" orientation="landscape">
|
||||||
<adaptation id="light"/>
|
<adaptation id="light"/>
|
||||||
</device>
|
</device>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="tvOS"/>
|
<deployment identifier="tvOS"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14283.14"/>
|
||||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
@@ -39,7 +39,6 @@
|
|||||||
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" prefetchingEnabled="YES" id="8P0-wP-bDe">
|
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" prefetchingEnabled="YES" id="8P0-wP-bDe">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1920" height="1080"/>
|
<rect key="frame" x="0.0" y="0.0" width="1920" height="1080"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="backgroundColor" red="0.33333334329999997" green="0.33333334329999997" blue="0.33333334329999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="50" minimumInteritemSpacing="50" id="m6l-TM-5FZ">
|
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="50" minimumInteritemSpacing="50" id="m6l-TM-5FZ">
|
||||||
<size key="itemSize" width="300" height="400"/>
|
<size key="itemSize" width="300" height="400"/>
|
||||||
<size key="headerReferenceSize" width="0.0" height="0.0"/>
|
<size key="headerReferenceSize" width="0.0" height="0.0"/>
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>StringsTable</key>
|
||||||
|
<string>Root</string>
|
||||||
|
<key>PreferenceSpecifiers</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSGroupSpecifier</string>
|
||||||
|
<key>Title</key>
|
||||||
|
<string>Host Configuration</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSToggleSwitchSpecifier</string>
|
||||||
|
<key>DefaultValue</key>
|
||||||
|
<false/>
|
||||||
|
<key>Title</key>
|
||||||
|
<string>Play Audio on Host PC</string>
|
||||||
|
<key>Key</key>
|
||||||
|
<string>audioOnPC</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>TrueValue</key>
|
||||||
|
<string>Optimize Games</string>
|
||||||
|
<key>FalseValue</key>
|
||||||
|
<string>Off</string>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSToggleSwitchSpecifier</string>
|
||||||
|
<key>Title</key>
|
||||||
|
<string>Optimize Games</string>
|
||||||
|
<key>Key</key>
|
||||||
|
<string>optimizeGames</string>
|
||||||
|
<key>DefaultValue</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSToggleSwitchSpecifier</string>
|
||||||
|
<key>Title</key>
|
||||||
|
<string>HEVC Video</string>
|
||||||
|
<key>Key</key>
|
||||||
|
<string>useHevc</string>
|
||||||
|
<key>DefaultValue</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSToggleSwitchSpecifier</string>
|
||||||
|
<key>Title</key>
|
||||||
|
<string>Enable HDR</string>
|
||||||
|
<key>Key</key>
|
||||||
|
<string>enableHdr</string>
|
||||||
|
<key>DefaultValue</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSGroupSpecifier</string>
|
||||||
|
<key>Title</key>
|
||||||
|
<string>Stream Configuration</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSMultiValueSpecifier</string>
|
||||||
|
<key>Title</key>
|
||||||
|
<string>Stream Resolution</string>
|
||||||
|
<key>Key</key>
|
||||||
|
<string>streamResolution</string>
|
||||||
|
<key>DefaultValue</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>Values</key>
|
||||||
|
<array>
|
||||||
|
<string>0</string>
|
||||||
|
<string>1</string>
|
||||||
|
<string>2</string>
|
||||||
|
</array>
|
||||||
|
<key>Titles</key>
|
||||||
|
<array>
|
||||||
|
<string>720p</string>
|
||||||
|
<string>1080p</string>
|
||||||
|
<string>4K</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSMultiValueSpecifier</string>
|
||||||
|
<key>Title</key>
|
||||||
|
<string>Frame Rate</string>
|
||||||
|
<key>Key</key>
|
||||||
|
<string>framerate</string>
|
||||||
|
<key>DefaultValue</key>
|
||||||
|
<string>60</string>
|
||||||
|
<key>Values</key>
|
||||||
|
<array>
|
||||||
|
<string>30</string>
|
||||||
|
<string>60</string>
|
||||||
|
</array>
|
||||||
|
<key>Titles</key>
|
||||||
|
<array>
|
||||||
|
<string>30 FPS</string>
|
||||||
|
<string>60 FPS</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>PSMultiValueSpecifier</string>
|
||||||
|
<key>Title</key>
|
||||||
|
<string>Bitrate</string>
|
||||||
|
<key>Key</key>
|
||||||
|
<string>bitrate</string>
|
||||||
|
<key>DefaultValue</key>
|
||||||
|
<string>10000</string>
|
||||||
|
<key>Titles</key>
|
||||||
|
<array>
|
||||||
|
<string>0.5 Mbps</string>
|
||||||
|
<string>1 Mbps</string>
|
||||||
|
<string>2 Mbps</string>
|
||||||
|
<string>5 Mbps</string>
|
||||||
|
<string>10 Mbps</string>
|
||||||
|
<string>20 Mbps</string>
|
||||||
|
<string>25 Mbps</string>
|
||||||
|
<string>50 Mbps</string>
|
||||||
|
<string>100 Mbps</string>
|
||||||
|
</array>
|
||||||
|
<key>Values</key>
|
||||||
|
<array>
|
||||||
|
<string>500</string>
|
||||||
|
<string>1000</string>
|
||||||
|
<string>2000</string>
|
||||||
|
<string>5000</string>
|
||||||
|
<string>10000</string>
|
||||||
|
<string>20000</string>
|
||||||
|
<string>25000</string>
|
||||||
|
<string>50000</string>
|
||||||
|
<string>100000</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
693B3A9B218638CD00982F7B /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 693B3A9A218638CD00982F7B /* Settings.bundle */; };
|
||||||
9832D1361BBCD5C50036EF48 /* TemporaryApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 9832D1351BBCD5C50036EF48 /* TemporaryApp.m */; };
|
9832D1361BBCD5C50036EF48 /* TemporaryApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 9832D1351BBCD5C50036EF48 /* TemporaryApp.m */; };
|
||||||
9865DC30213260B40005B9B9 /* libmoonlight-common-tv.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FB1A68152132509400507771 /* libmoonlight-common-tv.a */; };
|
9865DC30213260B40005B9B9 /* libmoonlight-common-tv.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FB1A68152132509400507771 /* libmoonlight-common-tv.a */; };
|
||||||
9865DC31213260F10005B9B9 /* mkcert.c in Sources */ = {isa = PBXBuildFile; fileRef = FB89460719F646E200339C8A /* mkcert.c */; };
|
9865DC31213260F10005B9B9 /* mkcert.c in Sources */ = {isa = PBXBuildFile; fileRef = FB89460719F646E200339C8A /* mkcert.c */; };
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
693B3A9A218638CD00982F7B /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; };
|
||||||
98132E8C20BC9A62007A053F /* Moonlight v1.1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.1.xcdatamodel"; sourceTree = "<group>"; };
|
98132E8C20BC9A62007A053F /* Moonlight v1.1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.1.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
9832D1341BBCD5C50036EF48 /* TemporaryApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TemporaryApp.h; path = Database/TemporaryApp.h; sourceTree = "<group>"; };
|
9832D1341BBCD5C50036EF48 /* TemporaryApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TemporaryApp.h; path = Database/TemporaryApp.h; sourceTree = "<group>"; };
|
||||||
9832D1351BBCD5C50036EF48 /* TemporaryApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TemporaryApp.m; path = Database/TemporaryApp.m; sourceTree = "<group>"; };
|
9832D1351BBCD5C50036EF48 /* TemporaryApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TemporaryApp.m; path = Database/TemporaryApp.m; sourceTree = "<group>"; };
|
||||||
@@ -440,6 +442,7 @@
|
|||||||
FB1A67612132419A00507771 /* Assets.xcassets */,
|
FB1A67612132419A00507771 /* Assets.xcassets */,
|
||||||
FB1A67632132419A00507771 /* Info.plist */,
|
FB1A67632132419A00507771 /* Info.plist */,
|
||||||
FB1A67642132419A00507771 /* main.m */,
|
FB1A67642132419A00507771 /* main.m */,
|
||||||
|
693B3A9A218638CD00982F7B /* Settings.bundle */,
|
||||||
);
|
);
|
||||||
path = "Moonlight TV";
|
path = "Moonlight TV";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -968,6 +971,7 @@
|
|||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
693B3A9B218638CD00982F7B /* Settings.bundle in Resources */,
|
||||||
FB1A681E21328A1B00507771 /* Images.xcassets in Resources */,
|
FB1A681E21328A1B00507771 /* Images.xcassets in Resources */,
|
||||||
FB1A67622132419A00507771 /* Assets.xcassets in Resources */,
|
FB1A67622132419A00507771 /* Assets.xcassets in Resources */,
|
||||||
FB1A67602132419700507771 /* Main.storyboard in Resources */,
|
FB1A67602132419700507771 /* Main.storyboard in Resources */,
|
||||||
|
|||||||