From 2cb1acc61104634885d14f6b7f870573a2d4886a Mon Sep 17 00:00:00 2001 From: Diego Waxemberg Date: Mon, 29 Dec 2014 00:11:14 -0500 Subject: [PATCH] Added analog sticks to onscreen controls --- .../StickInner.imageset/Contents.json | 23 ++++ .../StickInner.imageset/stick_inner-1.png | Bin 0 -> 1104 bytes .../StickInner.imageset/stick_inner-2.png | Bin 0 -> 1104 bytes .../StickInner.imageset/stick_inner.png | Bin 0 -> 1104 bytes .../StickOuter.imageset/Contents.json | 23 ++++ .../StickOuter.imageset/stick_outer-1.png | Bin 0 -> 1678 bytes .../StickOuter.imageset/stick_outer-2.png | Bin 0 -> 1678 bytes .../StickOuter.imageset/stick_outer.png | Bin 0 -> 1678 bytes Limelight/Input/OnScreenControls.h | 2 + Limelight/Input/OnScreenControls.m | 121 ++++++++++++++++-- Limelight/Input/StreamView.m | 2 +- 11 files changed, 157 insertions(+), 14 deletions(-) create mode 100644 Limelight/Images.xcassets/StickInner.imageset/Contents.json create mode 100644 Limelight/Images.xcassets/StickInner.imageset/stick_inner-1.png create mode 100644 Limelight/Images.xcassets/StickInner.imageset/stick_inner-2.png create mode 100644 Limelight/Images.xcassets/StickInner.imageset/stick_inner.png create mode 100644 Limelight/Images.xcassets/StickOuter.imageset/Contents.json create mode 100644 Limelight/Images.xcassets/StickOuter.imageset/stick_outer-1.png create mode 100644 Limelight/Images.xcassets/StickOuter.imageset/stick_outer-2.png create mode 100644 Limelight/Images.xcassets/StickOuter.imageset/stick_outer.png diff --git a/Limelight/Images.xcassets/StickInner.imageset/Contents.json b/Limelight/Images.xcassets/StickInner.imageset/Contents.json new file mode 100644 index 00000000..a9f35e77 --- /dev/null +++ b/Limelight/Images.xcassets/StickInner.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x", + "filename" : "stick_inner-1.png" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "stick_inner.png" + }, + { + "idiom" : "universal", + "scale" : "3x", + "filename" : "stick_inner-2.png" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Limelight/Images.xcassets/StickInner.imageset/stick_inner-1.png b/Limelight/Images.xcassets/StickInner.imageset/stick_inner-1.png new file mode 100644 index 0000000000000000000000000000000000000000..c09763aba5e458146fb9deb52b3081bde0727388 GIT binary patch literal 1104 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 literal 0 HcmV?d00001 diff --git a/Limelight/Images.xcassets/StickOuter.imageset/stick_outer-2.png b/Limelight/Images.xcassets/StickOuter.imageset/stick_outer-2.png new file mode 100644 index 0000000000000000000000000000000000000000..5748edeaef21da1723a186abc4cf13c9ef17d5ee GIT binary patch literal 1678 zcmeAS@N?(olHy`uVBq!ia0y~yU|0ac9Bd2>4Bh9`br~4gWISCQLn>~)ox9s#+EJi= zz0b=@msB^kq#XPixXb6|q)%R6US0wmnt>uBE-gRuiyyzyY`Zb%{PyjeH~(JyrBlSl zY`gvWH#TMKH6-32E7~c;-F zd$oSM;tJNvyBs0U4CeZ|ukm1Oy1glF`$k3ihD|#9N25-~L>fL$wvnr!cyx*@Z|2<^ zu1}91CB;S`U->6KB2d{`OeakHI{QzB&fRIP%Dgg1qL!%bIH8Fx~WTtyb zE}h{ODDp^Z`yIvp_N#|=S4Y?uN_MbjcU(Q4kna(CbZOX&uElAR(iWMVoUf1n+BnpBb{MRD;BsWTQ{8&82ife5`>tO6xc6&~;v;648^*Vm z&dZ)J%E&G-L&46)V;+A<=f1i(eJ-0KIE8bYSMPq-EnH8hI=Q5l4JM1MM zPLW<=s<|UP<>Q6~13TLbdihJAC^pWLKK8e1mbBWh)_{UrypMMKHZr>}sA`*GEWaR3 zI_*FEs^1Q?_#M7p5Sn{_K~=-tcj5tO*)P>_t!m`pXSu>8_%h^aVnft)6G4L&ZiieB zERf<pc}EkwUvR9(di!36UT-)y$g?bp5HyoT`ud>^J@9jwTp!o2;cWU8yz|A ze#DBD*W2%>^xloS@2Yqp_akTb(MRmvQ`I(YJ8Sh@DDmOL;E#JuHCbl#GaS8byP9jm zyd#&twFo4{F_qY?9VX#_b$MhdkjA3@J9SolZ7Vv+p%yzpWrpV+I z-!SjU^X<}ZYAV8CObk0Vi#)IH)z(vGGBukna&Z#>D&3zkr@6bTPpKX^a{L~lX8yQY zY?1A{XAFDGYVzD!b??Rc9r>EGK;eL?ct}$o%NfzV3#1t9cc{;5XL`siz$6&J>rfHM zyW&biWvIBz=KqgVO&9F?uPo2OSk0whnP_@s;{V?k89ogOyd1yTUP?$zSd}5YBT?eQ zFW+cZ4-+0|#ami@k}ii0GQNA?R?y^ioOE8d+VS23&V51p*IlnW_A9XP+Lf^?Z@&4a zjh*A*TKO=6rVzUgO$I89<~9fG|7NRgy3ibYu{?qG;f=lV`LB=12{gIwi*O9+uUXmW z@L`oZdw9&pf`id#x4&MHD9Yx)`+`2lai!Z^l#VROmTKA+7h||$cU+7iOMlhNIc*A0 zx7l%KNrhWJU1p^=`6OqkP}bg6&adipyy6_&CFUtDb3DxS)9$O{P6e?JJ@H&`kG(Te ziWf>r25UOjbO?MBx!-P`R&e~-&C2sDQPH(DN z_xx`e$EUqw*}JoHLrn~1wm9s!=J;?mV%AfwS;v@)TB~&*G;_Qb_;~XBq{qfePTsz2 zbCtHJ*%R4|rT?Vs8M36;&V2qPatZ?jgKmjyL`iUdT1k0gQ7S`HrCw4_ett?yrCxGT rWkE^4US@7$da7Q4pSzKXYhH4GN@~#xw)%Gr3=9mOu6{1-oD!M<6%zB+ literal 0 HcmV?d00001 diff --git a/Limelight/Images.xcassets/StickOuter.imageset/stick_outer.png b/Limelight/Images.xcassets/StickOuter.imageset/stick_outer.png new file mode 100644 index 0000000000000000000000000000000000000000..5748edeaef21da1723a186abc4cf13c9ef17d5ee GIT binary patch literal 1678 zcmeAS@N?(olHy`uVBq!ia0y~yU|0ac9Bd2>4Bh9`br~4gWISCQLn>~)ox9s#+EJi= zz0b=@msB^kq#XPixXb6|q)%R6US0wmnt>uBE-gRuiyyzyY`Zb%{PyjeH~(JyrBlSl zY`gvWH#TMKH6-32E7~c;-F zd$oSM;tJNvyBs0U4CeZ|ukm1Oy1glF`$k3ihD|#9N25-~L>fL$wvnr!cyx*@Z|2<^ zu1}91CB;S`U->6KB2d{`OeakHI{QzB&fRIP%Dgg1qL!%bIH8Fx~WTtyb zE}h{ODDp^Z`yIvp_N#|=S4Y?uN_MbjcU(Q4kna(CbZOX&uElAR(iWMVoUf1n+BnpBb{MRD;BsWTQ{8&82ife5`>tO6xc6&~;v;648^*Vm z&dZ)J%E&G-L&46)V;+A<=f1i(eJ-0KIE8bYSMPq-EnH8hI=Q5l4JM1MM zPLW<=s<|UP<>Q6~13TLbdihJAC^pWLKK8e1mbBWh)_{UrypMMKHZr>}sA`*GEWaR3 zI_*FEs^1Q?_#M7p5Sn{_K~=-tcj5tO*)P>_t!m`pXSu>8_%h^aVnft)6G4L&ZiieB zERf<pc}EkwUvR9(di!36UT-)y$g?bp5HyoT`ud>^J@9jwTp!o2;cWU8yz|A ze#DBD*W2%>^xloS@2Yqp_akTb(MRmvQ`I(YJ8Sh@DDmOL;E#JuHCbl#GaS8byP9jm zyd#&twFo4{F_qY?9VX#_b$MhdkjA3@J9SolZ7Vv+p%yzpWrpV+I z-!SjU^X<}ZYAV8CObk0Vi#)IH)z(vGGBukna&Z#>D&3zkr@6bTPpKX^a{L~lX8yQY zY?1A{XAFDGYVzD!b??Rc9r>EGK;eL?ct}$o%NfzV3#1t9cc{;5XL`siz$6&J>rfHM zyW&biWvIBz=KqgVO&9F?uPo2OSk0whnP_@s;{V?k89ogOyd1yTUP?$zSd}5YBT?eQ zFW+cZ4-+0|#ami@k}ii0GQNA?R?y^ioOE8d+VS23&V51p*IlnW_A9XP+Lf^?Z@&4a zjh*A*TKO=6rVzUgO$I89<~9fG|7NRgy3ibYu{?qG;f=lV`LB=12{gIwi*O9+uUXmW z@L`oZdw9&pf`id#x4&MHD9Yx)`+`2lai!Z^l#VROmTKA+7h||$cU+7iOMlhNIc*A0 zx7l%KNrhWJU1p^=`6OqkP}bg6&adipyy6_&CFUtDb3DxS)9$O{P6e?JJ@H&`kG(Te ziWf>r25UOjbO?MBx!-P`R&e~-&C2sDQPH(DN z_xx`e$EUqw*}JoHLrn~1wm9s!=J;?mV%AfwS;v@)TB~&*G;_Qb_;~XBq{qfePTsz2 zbCtHJ*%R4|rT?Vs8M36;&V2qPatZ?jgKmjyL`iUdT1k0gQ7S`HrCw4_ett?yrCxGT rWkE^4US@7$da7Q4pSzKXYhH4GN@~#xw)%Gr3=9mOu6{1-oD!M<6%zB+ literal 0 HcmV?d00001 diff --git a/Limelight/Input/OnScreenControls.h b/Limelight/Input/OnScreenControls.h index f9618689..f157e6c3 100644 --- a/Limelight/Input/OnScreenControls.h +++ b/Limelight/Input/OnScreenControls.h @@ -13,4 +13,6 @@ - (id) initWithView:(UIView*)view; - (void) handleTouchDownEvent:(UIEvent*)event; - (void) handleTouchUpEvent:(UIEvent*) event; +- (void) handleTouchMovedEvent:(UIEvent*)event; + @end diff --git a/Limelight/Input/OnScreenControls.m b/Limelight/Input/OnScreenControls.m index 8104d1b2..a00cc741 100644 --- a/Limelight/Input/OnScreenControls.m +++ b/Limelight/Input/OnScreenControls.m @@ -13,8 +13,6 @@ (y) ? (buttonFlags | (x)) : (buttonFlags & ~(x))) @implementation OnScreenControls { - UIView* _view; - BOOL shouldDrawControls; CALayer* _aButton; CALayer* _bButton; CALayer* _xButton; @@ -23,11 +21,19 @@ CALayer* _downButton; CALayer* _leftButton; CALayer* _rightButton; + CALayer* _leftStick; + CALayer* _rightStick; short buttonFlags; short leftStickX, leftStickY; short rightStickX, rightStickY; char leftTrigger, rightTrigger; + + UITouch* lsTouch; + UITouch* rsTouch; + + UIView* _view; + BOOL shouldDrawControls; } static const float BUTTON_SIZE = 50; @@ -41,17 +47,30 @@ static const float D_PAD_DIST = 15; static float D_PAD_CENTER_X; static float D_PAD_CENTER_Y; +static const float STICK_INNER_SIZE = 80; +static const float STICK_OUTER_SIZE = 120; +static float LS_CENTER_X; +static float LS_CENTER_Y; +static float RS_CENTER_X; +static float RS_CENTER_Y; + - (id) initWithView:(UIView*)view { self = [self init]; _view = view; shouldDrawControls = YES; D_PAD_CENTER_X = _view.frame.size.width * .15; - D_PAD_CENTER_Y = _view.frame.size.height * .75; + D_PAD_CENTER_Y = _view.frame.size.height * .5; BUTTON_CENTER_X = _view.frame.size.width * .85; - BUTTON_CENTER_Y = _view.frame.size.height * .75; + BUTTON_CENTER_Y = _view.frame.size.height * .5; + + LS_CENTER_X = _view.frame.size.width * .35; + LS_CENTER_Y = _view.frame.size.height * .75; + RS_CENTER_X = _view.frame.size.width * .65; + RS_CENTER_Y = _view.frame.size.height * .75; [self drawButtons]; + [self drawSticks]; return self; } @@ -105,6 +124,73 @@ static float D_PAD_CENTER_Y; [_view.layer addSublayer:_leftButton]; } +- (void) drawSticks { + // create left analog stick + CALayer* leftStickBackground = [CALayer layer]; + leftStickBackground.frame = CGRectMake(LS_CENTER_X - STICK_OUTER_SIZE / 2, LS_CENTER_Y - STICK_OUTER_SIZE / 2, STICK_OUTER_SIZE, STICK_OUTER_SIZE); + leftStickBackground.contents = (id) [UIImage imageNamed:@"StickOuter"].CGImage; + [_view.layer addSublayer:leftStickBackground]; + + _leftStick = [CALayer layer]; + _leftStick.frame = CGRectMake(LS_CENTER_X - STICK_INNER_SIZE / 2, LS_CENTER_Y - STICK_INNER_SIZE / 2, STICK_INNER_SIZE, STICK_INNER_SIZE); + _leftStick.contents = (id) [UIImage imageNamed:@"StickInner"].CGImage; + [_view.layer addSublayer:_leftStick]; + + // create right analog stick + CALayer* rightStickBackground = [CALayer layer]; + rightStickBackground.frame = CGRectMake(RS_CENTER_X - STICK_OUTER_SIZE / 2, RS_CENTER_Y - STICK_OUTER_SIZE / 2, STICK_OUTER_SIZE, STICK_OUTER_SIZE); + rightStickBackground.contents = (id) [UIImage imageNamed:@"StickOuter"].CGImage; + [_view.layer addSublayer:rightStickBackground]; + + _rightStick = [CALayer layer]; + _rightStick.frame = CGRectMake(RS_CENTER_X - STICK_INNER_SIZE / 2, RS_CENTER_Y - STICK_INNER_SIZE / 2, STICK_INNER_SIZE, STICK_INNER_SIZE); + _rightStick.contents = (id) [UIImage imageNamed:@"StickInner"].CGImage; + [_view.layer addSublayer:_rightStick]; +} + +- (void) handleTouchMovedEvent:(UIEvent*)event { + float rsMaxX = RS_CENTER_X + STICK_OUTER_SIZE / 2 - STICK_INNER_SIZE / 2; + float rsMaxY = RS_CENTER_Y + STICK_OUTER_SIZE / 2 - STICK_INNER_SIZE / 2; + float rsMinX = RS_CENTER_X - STICK_OUTER_SIZE / 2 - STICK_INNER_SIZE / 2; + float rsMinY = RS_CENTER_Y - STICK_OUTER_SIZE / 2 - STICK_INNER_SIZE / 2; + float lsMaxX = LS_CENTER_X + STICK_OUTER_SIZE / 2 - STICK_INNER_SIZE / 2; + float lsMaxY = LS_CENTER_Y + STICK_OUTER_SIZE / 2 - STICK_INNER_SIZE / 2; + float lsMinX = LS_CENTER_X - STICK_OUTER_SIZE / 2 - STICK_INNER_SIZE / 2; + float lsMinY = LS_CENTER_Y - STICK_OUTER_SIZE / 2 - STICK_INNER_SIZE / 2; + + for (UITouch* touch in [event allTouches]) { + CGPoint touchLocation = [touch locationInView:_view]; + float xLoc = touchLocation.x - STICK_INNER_SIZE / 2; + float yLoc = touchLocation.y - STICK_INNER_SIZE / 2; + if (touch == lsTouch) { + if (xLoc > lsMaxX) xLoc = lsMaxX; + if (xLoc < lsMinX) xLoc = lsMinX; + if (yLoc > lsMaxY) yLoc = lsMaxY; + if (yLoc < lsMinY) yLoc = lsMinY; + + _leftStick.frame = CGRectMake(xLoc, yLoc, STICK_INNER_SIZE, STICK_INNER_SIZE); + + leftStickX = 0x7FFF * (xLoc - LS_CENTER_X) / (lsMaxX - LS_CENTER_X); + leftStickY = 0x7FFF * (yLoc - LS_CENTER_Y) / (lsMaxY - LS_CENTER_Y); + NSLog(@"Left Stick: x: %d y: %d", leftStickX, leftStickY); + + } else if (touch == rsTouch) { + if (xLoc > rsMaxX) xLoc = rsMaxX; + if (xLoc < rsMinX) xLoc = rsMinX; + if (yLoc > rsMaxY) yLoc = rsMaxY; + if (yLoc < rsMinY) yLoc = rsMinY; + + _rightStick.frame = CGRectMake(xLoc, yLoc, STICK_INNER_SIZE, STICK_INNER_SIZE); + + rightStickX = 0x7FFF * (xLoc - RS_CENTER_X) / (rsMaxX - RS_CENTER_X); + rightStickY = 0x7FFF * (yLoc - RS_CENTER_Y) / (rsMaxY - RS_CENTER_Y); + NSLog(@"Right Stick: x: %d y: %d", rightStickX, rightStickY); + } + } + LiSendControllerEvent(buttonFlags, leftTrigger, rightTrigger, + leftStickX, leftStickY, rightStickX, rightStickY); +} + - (void)handleTouchDownEvent:(UIEvent*)event { for (UITouch* touch in [event allTouches]) { CGPoint touchLocation = [touch locationInView:_view]; @@ -125,21 +211,25 @@ static float D_PAD_CENTER_Y; UPDATE_BUTTON(LEFT_FLAG, 1); } else if ([_rightButton.presentationLayer hitTest:touchLocation]) { UPDATE_BUTTON(RIGHT_FLAG, 1); + } else if ([_leftStick.presentationLayer hitTest:touchLocation]) { + lsTouch = touch; + } else if ([_rightStick.presentationLayer hitTest:touchLocation]) { + rsTouch = touch; } /* - UPDATE_BUTTON(LB_FLAG, gamepad.leftShoulder.pressed); - UPDATE_BUTTON(RB_FLAG, gamepad.rightShoulder.pressed); + UPDATE_BUTTON(LB_FLAG, gamepad.leftShoulder.pressed); + UPDATE_BUTTON(RB_FLAG, gamepad.rightShoulder.pressed); - leftStickX = gamepad.leftThumbstick.xAxis.value * 0x7FFE; - leftStickY = gamepad.leftThumbstick.yAxis.value * 0x7FFE; + leftStickX = gamepad.leftThumbstick.xAxis.value * 0x7FFE; + leftStickY = gamepad.leftThumbstick.yAxis.value * 0x7FFE; - rightStickX = gamepad.rightThumbstick.xAxis.value * 0x7FFE; - rightStickY = gamepad.rightThumbstick.yAxis.value * 0x7FFE; + rightStickX = gamepad.rightThumbstick.xAxis.value * 0x7FFE; + rightStickY = gamepad.rightThumbstick.yAxis.value * 0x7FFE; - leftTrigger = gamepad.leftTrigger.value * 0xFF; - rightTrigger = gamepad.rightTrigger.value * 0xFF; - */ + leftTrigger = gamepad.leftTrigger.value * 0xFF; + rightTrigger = gamepad.rightTrigger.value * 0xFF; + */ // We call LiSendControllerEvent while holding a lock to prevent // multiple simultaneous calls since this function isn't thread safe. } @@ -169,6 +259,11 @@ static float D_PAD_CENTER_Y; } else if ([_rightButton.presentationLayer hitTest:touchLocation]) { UPDATE_BUTTON(RIGHT_FLAG, 0); } + if (touch == lsTouch) { + _leftStick.frame = CGRectMake(LS_CENTER_X - STICK_INNER_SIZE / 2, LS_CENTER_Y - STICK_INNER_SIZE / 2, STICK_INNER_SIZE, STICK_INNER_SIZE); + } else if (touch == rsTouch) { + _rightStick.frame = CGRectMake(RS_CENTER_X - STICK_INNER_SIZE / 2, RS_CENTER_Y - STICK_INNER_SIZE / 2, STICK_INNER_SIZE, STICK_INNER_SIZE); + } /* UPDATE_BUTTON(LB_FLAG, gamepad.leftShoulder.pressed); UPDATE_BUTTON(RB_FLAG, gamepad.rightShoulder.pressed); diff --git a/Limelight/Input/StreamView.m b/Limelight/Input/StreamView.m index 748ed989..a1dbb6d7 100644 --- a/Limelight/Input/StreamView.m +++ b/Limelight/Input/StreamView.m @@ -29,7 +29,7 @@ } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - + [onScreenControls handleTouchMovedEvent:event]; if ([[event allTouches] count] == 1) { UITouch *touch = [[event allTouches] anyObject]; CGPoint currentLocation = [touch locationInView:self];