OUYA support

Will there be OUYA support by cocos2dx, when it comes out? For those of you who don’t know what the OUYA is, here is a link to their kickstarter project: http://www.kickstarter.com/projects/ouya/ouya-a-new-kind-of-video-game-console?ref=live

I was wondering, how would you add support for the controllers? Also, the OUYA runs on android, that is why I put it in the android category.

I’m also interested in this. :slight_smile:

bump

I think they have to get an OUYA first :stuck_out_tongue:

I’m very interested in this as well. I’ve already started developing a game with cocos2d-x in hopes of having a head-start on things.

Cocos2d-x already supports Android so I think that the only thing left is to support their Gamepad

@Oren Bengigi
Yeah, so I guess what I was really asking is will anybody put in Gamepad support. This would also be nice on other systems such as windows. :slight_smile:

P.S. Once the OUYA officially comes and I finish a project I am working on, I would be willing to help if anybody wants it.

Hey everyone. We started a project template for our company and are using cocos2d-x for cross-platform development. We also target OUYA and wrote the first JNI bindings to use the controllers with cocos2d-x with OUYA. Feel free to check out our code at github:

We added a building target for OUYA and extended the Android code with a JNI for the controller you find the code under cocos2d/platform/ouya/…

Best Kie

Jacob Anderson, maintainer of cocos2d-xna is also targeting on OUYA using C#.
Is OUYA promising in USA and Europe? How may players purchase its devices?

hello. cocos2d-xna already runs on ouya. We will push the Ouya project files and solution to the repositories sooon.

There are a couple of “rogue” cocos2d-x variants out there who either are already, or are planning, to run on Ouya. If you are a registered developer with Ouya then check their forums to find these efforts.

We have an Ouya device in our office and have seen it actually run our latest title - Santa Shooter (which is available on Android, Windows, and iTunes markets).

There is no official NDK from Ouya yet for their platform. For cocos2d-x to work on Ouya you need the NDK.

Also, if you want to make some cash, there is a competition starting in 3 days:

http://killscreendaily.com/create/

Hey guys,

I know that this thread is a bit old… but is there any news on this subject? I have my Ouya and I would like to port one game also to this platform.

Thanks

Alejandro Santiago wrote:

Hey guys,
>
I know that this thread is a bit old… but is there any news on this subject? I have my Ouya and I would like to port one game also to this platform.
>
Thanks

Your game/app will likely run just fine after you follow downloading and preparing your android build in Eclipse from the ODK instructions. I believe you will need to add ouya-sdk.jar to the lib folder in order for it to work.

After you get the game to load and running you’ll have to then add support for the new interface. Controller buttons map to keys. But if you’re not using standard Android UI for your menus you’ll have to write code to handle pressing up/down/left/right to move from button to button and selecting the buttons. This is where the work porting to OUYA will be mostly focused. In-App purchases and a few other things will also be involved, including keeping game inside the safe area for the various TV size/resolutions.

See: https://devs.ouya.tv/developers/docs/controllers

I believe initial keyboard support is in the develop branch of cocos2d-x, but now that’s been hijacked for v3.x. I’m not sure how easy it would be to cherry pick the desired functionality, but I’d guess you’d just need to look in CCKeyboardDispatcher/CCKeyboardDelegate/CCEventDispatcher for the various platforms you need to support, copy the correct code to detect the platform key up/down and for example Android you’ll have to make sure the code passes through the JNI layer correctly, so there will likely be a little extra work for OUYA/Android.

So, here’s what I did for simple controller integration for testing I worked on today. Code could be improved, some stuff probably unnecessary, no error checking, etc. YMMV.

Changes to the engine:

cocos2dx/keypad_dispatcher/CCKeypadDelegate.h (46)

    // The menu key clicked. only available on wophone & android
    virtual void keypadDown(int keyCode) {};

cocos2dx/keypad_dispatcher/CCKeypadDispatcher.h (80)

    /**
    @brief dispatch the keydown event
    */
    bool dispatchKeypadDown(int keyCode);

cocos2dx/keypad_dispatcher/CCKeypadDispatcher.cpp (175)

bool CCKeypadDispatcher::dispatchKeypadDown(int keyCode)
{
    CCKeypadHandler*  pHandler = NULL;
    CCKeypadDelegate* pDelegate = NULL;

    m_bLocked = true;

    if (m_pDelegates->count() > 0)
    {
        CCObject* pObj = NULL;
        CCARRAY_FOREACH(m_pDelegates, pObj)
        {
            CC_BREAK_IF(!pObj);

            pHandler = (CCKeypadHandler*)pObj;
            pDelegate = pHandler->getDelegate();

            pDelegate->keypadDown(keyCode);
        }
    }

    m_bLocked = false;
    if (m_bToRemove)
    {
        m_bToRemove = false;
        for (unsigned int i = 0; i < m_pHandlersToRemove->num; ++i)
        {
            forceRemoveDelegate((CCKeypadDelegate*)m_pHandlersToRemove->arr[i]);
        }
        ccCArrayRemoveAllValues(m_pHandlersToRemove);
    }

    if (m_bToAdd)
    {
        m_bToAdd = false;
        for (unsigned int i = 0; i < m_pHandlersToAdd->num; ++i)
        {
            forceAddDelegate((CCKeypadDelegate*)m_pHandlersToAdd->arr[i]);
        }
        ccCArrayRemoveAllValues(m_pHandlersToAdd);
    }

    return true;
}

cocos2dx/layers_scenes_transitions_nodes/CCLayer.h (147)

    virtual void keypadDown(int);

cocos2dx/layers_scenes_transitions_nodes/CCLayer.cpp (330)

void CCLayer::keypadDown(int)
{
}

cocos2dx/platform/android/jni/TouchesJni.cpp (85)

            default:
                if (pDirector->getKeypadDispatcher()->dispatchKeypadDown(keyCode))
                    return JNI_TRUE;
                return JNI_FALSE;

If you have subclassed Cocos2dxGLSurfaceView in Java then you will probably want to override the keydown in your activity and might need access to the render to call the native methods.

cocos2dx/platform/android/java/src/org/cocos2dx/lib/Cocos2dxGLSurfaceView.java (58)

    public Cocos2dxRenderer mCocos2dxRenderer;

Code in game project:

GAME_ACTIVITY_CLASS_NAME.java

import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;

import tv.ouya.console.api.OuyaController;

public class _GAME_ACTIVITY_CLASS_NAME_ extends Cocos2dxActivity {

    private static final String TAG = _GAME_ACTIVITY_CLASS_NAME_.class.getSimpleName();

    public Cocos2dxGLSurfaceView mGLView;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        OuyaController.init(this);
    }

    public Cocos2dxGLSurfaceView onCreateView() {
        mGLView = new GameSurfaceView(this);

        // should create stencil buffer
        mGLView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
        return mGLView;
    }

    @Override
    public boolean onKeyDown(final int keyCode, KeyEvent event) {
        boolean handled = false;

        Log.d(TAG, "keycode = " + keyCode);
        handled = OuyaController.onKeyDown(keyCode, event);
        Log.d(TAG, "device id = " + event.getDeviceId());

        if (keyCode == OuyaController.BUTTON_MENU) {
            AlertDialog ad = new AlertDialog.Builder(this)
            .setTitle("EXIT?")
            .setMessage("Do you really want to exit?")
            .setPositiveButton("YES",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            android.os.Process.killProcess(android.os.Process.myPid());
                            //myActivity.finish();
                        }
                    })
            .setNegativeButton("NO",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {

                        }
                    }).create();
            ad.show();
        }

        Log.d(TAG, "try to send key " + keyCode + " to native");    

        this.mGLView.queueEvent(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "sending key " + keyCode + " down to native");   
                _GAME_ACTIVITY_CLASS_NAME_.this.mGLView.mCocos2dxRenderer.handleKeyDown(keyCode);
            }
        });

        return handled || super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        boolean handled = false;
        handled = OuyaController.onKeyUp(keyCode, event);
        return handled || super.onKeyUp(keyCode, event);
    }

    //@Override
    public boolean onGenericMotionEvent(MotionEvent event) {
        boolean handled = false;    
        handled = OuyaController.onGenericMotionEvent(event);
        OuyaController c = OuyaController.getControllerByDeviceId(event.getDeviceId());
        if (c != null) {
            //Log.d(TAG, "x = " + c.getAxisValue(OuyaController.AXIS_LS_X));
            //Log.d(TAG, "y = " + c.getAxisValue(OuyaController.AXIS_LS_Y));
        }
        return handled;// || super.onGenericMotionEvent(event);
    }

    static {
        System.loadLibrary("game");
    }
}

class GameSurfaceView extends Cocos2dxGLSurfaceView {

    private _GAME_ACTIVITY_CLASS_NAME_ myActivity;

    public GameSurfaceView(Context context) {
        super(context);
        myActivity = (_GAME_ACTIVITY_CLASS_NAME_)context;
    }
}

Finally integrate the keypad handling in your game code:

Declare the delegate methods in the header file.

// key pad
virtual void keyBackClicked();
virtual void keyMenuClicked();
virtual void keypadDown(int keyCode);

Define the methods in your class file

void CLASS_NAME::keyBackClicked()
{
    CCLOG("back key pressed");
}
void CLASS_NAME::keyMenuClicked()
{
    CCLOG("menu key pressed");
}
void CLASS_NAME::keypadDown(int keyCode)
{
    CCLOG("[CLASS_NAME] Key with keycode %d pressed", keyCode);
    static const int OUYA_KEY_O = 96;
    static const int OUYA_KEY_U = 99;
    static const int OUYA_KEY_Y = 100;
    static const int OUYA_KEY_A = 97;
    switch(keyCode)
    {
        case OUYA_KEY_O:
            this->newGame(nullptr);
            break;
        case OUYA_KEY_U:
            this->resumeGame(nullptr);
            break;
        default:
            // etc
            break;
    }
}

Declare that you want to handle keypad events

void CLASS_NAME::init() 
{
    if ( !CCNode::init() )
    {
        return false;
    }

    setKeypadEnabled(true);
    // more code here
}

Hi Steve,

I have modified a cocos2d-x-2.1.4 version adding your code and also I have added this three methods in my project: keyBackClicked, keyMenuClicked and keypadDown. Unfortunatelly, I can’t get it working, the keypadDown method is never called. If I push some buttons, I get these logs but that function is never called:

08-14 09:58:43.594: D/Test(4853): keycode = 99
08-14 09:58:43.594: D/Test(4853): device id = 3
08-14 09:58:43.594: D/Test(4853): try to send key 99 to native
08-14 09:58:43.594: D/Test(4853): sending key 99 down to native

What I am missing? I think that I made all the changes, but seems that I’m missing something and I don’t know what it is. Can you help me, please?

Thanks :smiley:
Mikel.

Hey, sorry to not reply earlier, I guess when you reply it doesn’t automatically enable the “watch this post” functionality.

First thoughts:

  • CCLayer or a subclass of CCLayer is necessary to enable keypad support

  • forgot to enable it with setKeypadEnabled(true) within the CCLayer (or subclass)

  • code path may not be reaching the code added into TouchesJNI, so put a CCLOG before calling dispatchKeypadDown

    default:
    CCLOG(“dispatching keycode”);
    if (pDirector->getKeypadDispatcher()->dispatchKeypadDown(keyCode))

I’ll look over the latest code in case I made some changes to get it working that I forgot to mention.

Hi Steve,

sorry for the late response. I have been out for several days and I have had no time for responding earlier.

I removed all the changes I made and started again from scratch. I do not know what I did differently, but after having some problems with the libraries, I finally got it working. I have not done much testing, but I think all is fine, thanks :smiley:

Mikel.

Hi,

any chance of getting an “ouya” platform added to cocos2d-x similar to the others?

I followed the implementation provided by Daniel above, http://www.github.com/levire/MetaProject, porting it to the cocos2d-x v3 branch, but I am still pretty new to cocos2d-x and android development in general and so my implementation feels less than ideal.

I read that the native NDK for C++ works for developing OUYA games so shouldn’t cocos2d-x 2.1.4 work as well sort of by default (besides maybe mapping the keys on the game controller)?

Yep, OUYA fully supports NDK projects. It’ll run your game with no changes. However, it may or may not be playable (hence need for controller support).

Has anyone implemented Ouya controller support with the latest rev of cocos2d-x version 3.0?

In previous revs, I was able to implement it using GLSurfaveView like shown above, but it in the latest source of cocos2d-x 3.0 that no longer exists.

Any suggestions on how to handle Ouya controller input with the latest cocos2d-x 3.0 source?