Skip to content

Instantly share code, notes, and snippets.

@giginet
Last active December 19, 2015 10:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save giginet/5939918 to your computer and use it in GitHub Desktop.
Save giginet/5939918 to your computer and use it in GitHub Desktop.
OUYA Development Kit (OuyaController) Wrapper for C++
/*
* OuyaController.cpp
*
* Created on: Jul 6, 2013
* Author: giginet
*/
#include "OuyaController.h"
#include "platform/android/jni/JniHelper.h"
#define CONTROLLER_CLASS_NAME "tv/ouya/console/api/OuyaController"
JNIEnv *Kawaz::OUYA::OuyaController::getJNIEnv() {
JavaVM* jvm = cocos2d::JniHelper::getJavaVM();
if (NULL == jvm) {
CCLOG("Failed to get JNIEnv. JniHelper::getJavaVM() is NULL");
return NULL;
}
JNIEnv *env = NULL;
// get jni environment
jint ret = jvm->GetEnv((void**) &env, JNI_VERSION_1_4);
switch (ret) {
case JNI_OK:
// Success!
return env;
case JNI_EDETACHED:
// Thread not attached
// TODO : If calling AttachCurrentThread() on a native thread
// must call DetachCurrentThread() in future.
// see: http://developer.android.com/guide/practices/design/jni.html
if (jvm->AttachCurrentThread(&env, NULL) < 0) {
CCLOG("Failed to get the environment using AttachCurrentThread()");
return NULL;
} else {
// Success : Attached and obtained JNIEnv!
return env;
}
case JNI_EVERSION:
// Cannot recover from this error
CCLOG("JNI interface version 1.4 not supported");
default:
CCLOG("Failed to get the environment using GetEnv()");
return NULL;
}
}
// get class and make it a global reference, release it at endJni().
jclass Kawaz::OUYA::OuyaController::getClassID(JNIEnv *pEnv,
const char *className) {
jclass ret = pEnv->FindClass(className);
if (!ret) {
CCLOG("Failed to find class of %s", className);
}
return ret;
}
bool Kawaz::OUYA::OuyaController::getStaticMethodInfo(JniMethodInfo &methodinfo,
const char *className, const char *methodName, const char *paramCode) {
jmethodID methodID = 0;
JNIEnv *pEnv = 0;
bool bRet = false;
do {
pEnv = getJNIEnv();
if (!pEnv) {
break;
}
jclass classID = getClassID(pEnv, className);
methodID = pEnv->GetStaticMethodID(classID, methodName, paramCode);
if (!methodID) {
CCLOG("Failed to find static method id of %s", methodName);
break;
}
methodinfo.classID = classID;
methodinfo.env = pEnv;
methodinfo.methodID = methodID;
bRet = true;
} while (0);
return bRet;
}
bool Kawaz::OUYA::OuyaController::getMethodInfo(JniMethodInfo &methodInfo,
const char *className, const char *methodName, const char *paramCode) {
jmethodID methodID = 0;
JNIEnv *pEnv = 0;
bool bRet = false;
do {
pEnv = getJNIEnv();
if (!pEnv) {
break;
}
jclass classID = getClassID(pEnv, className);
methodID = pEnv->GetMethodID(classID, methodName, paramCode);
if (!methodID) {
CCLOG("Failed to find method id of %s", methodName);
break;
}
methodInfo.classID = classID;
methodInfo.env = pEnv;
methodInfo.methodID = methodID;
bRet = true;
} while (0);
return bRet;
}
Kawaz::OUYA::OuyaController::OuyaController(jobject controllerObject) {
_controller = controllerObject;
}
Kawaz::OUYA::OuyaController::~OuyaController() {
// TODO Auto-generated destructor stub
JNIEnv *env = OuyaController::getJNIEnv();
env->DeleteLocalRef(_controller);
}
Kawaz::OUYA::OuyaController* Kawaz::OUYA::OuyaController::getControllerByDeviceId(
int deviceId) {
JniMethodInfo methodInfo;
if (!Kawaz::OUYA::OuyaController::getStaticMethodInfo(methodInfo,
CONTROLLER_CLASS_NAME, "getControllerByDeviceId",
"(I)Ltv/ouya/console/api/OuyaController;")) {
return NULL;
}
jobject cObj = methodInfo.env->CallStaticObjectMethod(methodInfo.classID,
methodInfo.methodID, deviceId);
OuyaController *controller = new OuyaController(cObj);
return controller;
}
Kawaz::OUYA::OuyaController* Kawaz::OUYA::OuyaController::getControllerByPlayer(
int playerNum) {
JniMethodInfo methodInfo;
if (!Kawaz::OUYA::OuyaController::getStaticMethodInfo(methodInfo,
CONTROLLER_CLASS_NAME, "getControllerByPlayer",
"(I)Ltv/ouya/console/api/OuyaController;")) {
return NULL;
}
jobject cObj = methodInfo.env->CallStaticObjectMethod(methodInfo.classID,
methodInfo.methodID, playerNum);
OuyaController *controller = new OuyaController(cObj);
return controller;
}
int Kawaz::OUYA::OuyaController::getPlayerNum() {
JniMethodInfo methodInfo;
if (!Kawaz::OUYA::OuyaController::getMethodInfo(methodInfo,
CONTROLLER_CLASS_NAME, "getPlayerNum", "()I")) {
return 0;
}
int num = methodInfo.env->CallIntMethod(_controller, methodInfo.methodID);
return num;
}
int Kawaz::OUYA::OuyaController::getDeviceId() {
JniMethodInfo methodInfo;
if (!Kawaz::OUYA::OuyaController::getMethodInfo(methodInfo,
CONTROLLER_CLASS_NAME, "getDeviceId", "()I")) {
return 0;
}
int deviceId = methodInfo.env->CallIntMethod(_controller,
methodInfo.methodID);
return deviceId;
}
bool Kawaz::OUYA::OuyaController::buttonChangedThisFrame(int ouyaButton) {
JniMethodInfo methodInfo;
if (!Kawaz::OUYA::OuyaController::getMethodInfo(methodInfo,
CONTROLLER_CLASS_NAME, "buttonChangeThisFrame", "(I)Z")) {
return false;
}
return methodInfo.env->CallBooleanMethod(_controller, methodInfo.methodID,
ouyaButton);
}
float Kawaz::OUYA::OuyaController::getAxisValue(int ouyaAxis) {
JniMethodInfo methodInfo;
if (!Kawaz::OUYA::OuyaController::getMethodInfo(methodInfo,
CONTROLLER_CLASS_NAME, "getAxisValue", "(I)F")) {
return 0;
}
jfloat f = methodInfo.env->CallFloatMethod(_controller, methodInfo.methodID, ouyaAxis);
methodInfo.env->DeleteLocalRef(methodInfo.classID);
return f;
}
bool Kawaz::OUYA::OuyaController::getButton(int ouyaButton) {
JniMethodInfo methodInfo;
if (!Kawaz::OUYA::OuyaController::getMethodInfo(methodInfo,
CONTROLLER_CLASS_NAME, "getButton", "(I)Z")) {
return false;
}
methodInfo.env->DeleteLocalRef(methodInfo.classID);
return methodInfo.env->CallBooleanMethod(_controller, methodInfo.methodID,
ouyaButton);
}
int Kawaz::OUYA::OuyaController::getPlayerNumByDeviceId(int deviceId) {
JniMethodInfo methodInfo;
if (!Kawaz::OUYA::OuyaController::getStaticMethodInfo(methodInfo,
CONTROLLER_CLASS_NAME, "getPlayerNumByDeviceId", "(I)I")) {
return 0;
}
return methodInfo.env->CallStaticIntMethod(methodInfo.classID,
methodInfo.methodID, deviceId);
}
void Kawaz::OUYA::OuyaController::startOfFrame() {
JniMethodInfo methodInfo;
if (!Kawaz::OUYA::OuyaController::getStaticMethodInfo(methodInfo,
CONTROLLER_CLASS_NAME, "startOfFrame", "()V")) {
}
methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID);
}
/*
* OuyaController.h
*
* Created on: Jul 6, 2013
* Author: giginet
*/
#ifndef OUYACONTROLLER_H_
#define OUYACONTROLLER_H_
#include <jni.h>
#include "cocos2d.h"
namespace Kawaz {
namespace OUYA {
typedef struct JniMethodInfo_ {
JNIEnv * env;
jclass classID;
jmethodID methodID;
} JniMethodInfo;
class OuyaController {
private:
jobject _controller;
OuyaController(jobject controllerObject);
static JNIEnv *getJNIEnv();
static jclass getClassID(JNIEnv *pEnv, const char *className);
static bool getStaticMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode);
static bool getMethodInfo(JniMethodInfo &methodInfo, const char *className, const char *methodName, const char *paramCode);
public:
virtual ~OuyaController();
static OuyaController* getControllerByDeviceId(int deviceId);
static OuyaController* getControllerByPlayer(int playerNum);
static int getPlayerNumByDeviceId(int deviceId);
/*static bool onGenericMotionEvent();
static bool onKeyDown(int keyCode);
static bool onKeyUp(int keyCode);*/
static void startOfFrame();
int getDeviceId();
int getPlayerNum();
bool buttonChangedThisFrame(int ouyaButton);
float getAxisValue(int ouyaAxis);
bool getButton(int ouyaButton);
static const int MAX_CONTROLLERS = 4;
static const float STICK_DEADZONE = 0.25f;
enum {
AXIS_L2 = 17,
AXIS_LS_X = 0,
AXIS_LS_Y = 1,
AXIS_R2 = 18,
AXIS_RS_X = 11,
AXIS_RS_Y = 14,
BUTTON_A = 97,
BUTTON_DPAD_DOWN = 20,
BUTTON_DPAD_LEFT = 21,
BUTTON_DPAD_RIGHT = 22,
BUTTON_DPAD_UP = 19,
BUTTON_L1 = 102,
BUTTON_L2 = 104,
BUTTON_L3 = 106,
BUTTON_MENU = 82,
BUTTON_O = 96,
BUTTON_R1 = 103,
BUTTON_R2 = 105,
BUTTON_R3 = 107,
BUTTON_U = 99,
BUTTON_Y = 100
};
};
}
}
#endif /* OUYACONTROLLER_H_ */
#include "OuyaController.h"
using namespace Kawaz::OUYA;
void MyScene::update(float dt) {
// Get OuyaController Object of Player 1 (PlayerID = 0)
OuyaController *controller = OuyaController::getControllerByPlayer(0);
if (controller != NULL) { // if controller was found.
float x = controller->getAxisValue(OuyaController::AXIS_LS_X); // X Axis value of Left Stick
float y = controller->getAxisValue(OuyaController::AXIS_LS_Y); // Y Axis value of Right Stick
bool o = controller->getButton(OuyaController::BUTTON_O); // get O button state.
if (o) {
CCLOG("Button O is pressed!");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment