Building for the new AppleTV / tvOS

I added GCMicroController support (for Apple remote) to tvOS branch, but it is impossible to test this since it doesn’t work in Apple TV simulator. I will try to add input with GCEventViewController later.

Do you know where are sources of all the dependent libraries?
Is there a “howto” build them?

Do you think that SpiderMonkey would be also compilable for TV?
Would you predict any other problem for Cocos-JS?

@elvman I’ll try to run your sample on the device tomorrow.

I am pretty sure SpiderMonkey is not yet ready for AppleTV, but it should be anytime soon.
@pepeek how did you get the device? :slight_smile:

Ok, it seems that GCEventViewController also doesn’t work on the simulator so no chance to test the controllers on AppleTV for now.

Your code isn’t working on the device either. Could only do a quick test, will look into it further later on. Just wanted to let you know that it is not only the simulator.

Ok, how did you test it?
Apple release notes say that gamecontroller framework is not working in the simulator: https://developer.apple.com/library/prerelease/tvos/releasenotes/General/RN-tvOSSDK-9.0/index.html#//apple_ref/doc/uid/TP40016575

Here is the code that I am testing it with:

#include "CCGameController.h"

void MyScene::update(float delta)
{
    static Controller* currentController = nullptr;
    
    if (currentController)
    {
        for (int i = cocos2d::Controller::JOYSTICK_LEFT_X; i < cocos2d::Controller::KEY_MAX; ++i)
        {
            if (currentController->getKeyStatus(i).isPressed)
            {
                log("Key %i down", i);
            }
        }
    }
    else
    {
        std::vector<Controller*> controllers = Controller::getAllController();
        for (Controller* controller : controllers)
        {
            log("Got controller %s", controller->getDeviceName().c_str());
            
            currentController = controller;
        }
    }
}

I updated cocos/base/CCController-iOS.mm from your repository. I then added all the code from the cocos2d-x/tests/game-controller-test/Classes/GameControllerTest.cpp class to my own layer. None of the callbacks fires. I have just now also added the code you provided to my update method and getAllController never returns anything.

Have I missed any updates in your repository besides the ones in CCController-iOS.mm? Anything else you would like me to try? I will further look into this now as I want to implement “pause/play” and “menu” button functionality.

In case anyone wants me to try something on the device, just let me know and I will.

Did you call “Controller::startDiscoveryController();” somewhere?
I found out that cocos2d-x touch events work with AppleTV and this is the only way to get input from Apple remote (except using UIKit, of course).

Yes, I called that, here ist the actual code used:

//controller callbacks
auto controllerListener = EventListenerController::create();

controllerListener->onConnected = CC_CALLBACK_2(IngameScene::onConnectController,this);
controllerListener->onDisconnected = CC_CALLBACK_2(IngameScene::onDisconnectedController,this);
controllerListener->onKeyDown = CC_CALLBACK_3(IngameScene::onKeyDown, this);
controllerListener->onKeyUp = CC_CALLBACK_3(IngameScene::onKeyUp, this);
controllerListener->onAxisEvent = CC_CALLBACK_3(IngameScene::onAxisEvent, this);

Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(controllerListener, this);

Controller::startDiscoveryController();

//tick
scheduleUpdate();

To clarify, I am not trying to get a bluetooth controller to work but the button events from the remote. I take it that requires the use of UIKit then? Will try to get my hands on a bluetooth controller and give that a try.

So how can we get UIKit get to work with cocos2d-x in order to assign functionality to the buttons? A game where the menu button always quits the game and the play/pause button does nothing is really bad UX imho.

edit: along with your code in the update function, copied as displayed in your post here.

edit2: none of the callbacks are being called, and the code in CCController-iOS.mm

[[GCControllerConnectionEventHandler getInstance] observerConnection: ^(GCController* gcController) { ... }

doesn’t get called either. Apparently the remote doesn’t count as a GCController?!

edit3: Apparently it does count as a GCController. I wonder why it doesn’t show up when getAllController is called. The relevant parts of the documentation are here https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/WorkingwithGameControllers.html

The documentation says that when input is transformed to higher level events, input does not also get delivered to the app. As the buttons still work, I assume this is the case. Workaround is to use a GCEventViewController, as you mentioned here. If you have some code to test, I will happily try this on the device.

Well that is weird, since for me “onConnectController” is being called a few seconds after “startDiscoveryController()”. And yes, Apple Remote is a GCMicroGamepad.

PS. Can i make a project for you to test it on the device?

Good news! @elvman was able to walk me through this and input from touch/play/pause and dpad are all working on the device. Switching my project to his fork/branch now. Thanks so much @elvman!

Edit: Running this with the original branch by @hawkwood also works, the reason I didn’t get this to work is that I had the controller code in the second scene of the project rather than the first. The second scene won’t receive the “onConnectController”!

Well, I am curious why @hawkwood’s code also works, since he hasn’t implemented GCMicroGamepad, and Apple remote is a micro gamepad, not normal or extended gamepad. I guess you get only “onControllerConnected”, but no the actual input.

This might be true, sorry for the confusion if I am wrong. Will try this tonight and report back. Maybe @hawkwood can add you as an admin to the repo so you can merge changes?

Could you please give me a short navigation how to create a test project. I’ve got the developers kit device and want to give it a try.

  1. Shall I use @hawkwood or @elvman repo?
  2. How do I create a sample project. I can see that there is a new appleTV target in the cocos2d_libs project but no such target in the sample project in templates. Would you give me a hint how to create it properly?

For now the samples can not be compiled for AppleTV. If you need a sample, you can download the code I am testing AppleTV with: https://github.com/elvman/tvos-test

I have added elvman as a collaborator.

As promised an update on the remote input. Using @hawkwood’s code, when RootViewController is set up like this

@interface RootViewController : UIViewController {

it will create this output when run on the device and pushing the menu button, which will fire the event and at the same time quit the app

onConnectController
Got controller Remote
onKeyDown
onKeyUp

Output is the same when

@interface RootViewController : GCEventViewController {

but it won’t quit the application when the menu button is pushed. In both cases, pushing play/pause does nothing. play/pause was working with @elvman’s code along with dpad emulation etc.

edit: Great news, using @elvman’s CCController-iOS code along with the onKeyUp/Down listeners, we can get all relevant events from the remote. Thanks guys!

Thank you @hawkwood, I pushed GCMicroGamepad support code to your repository.