Bluetooth controller connection problem

Version : cocos2d-x 3.10

hi everyone.

i wanted apply bluetooth controller on my game.
so i did the work…and i successed it.

but i found problem.
some sprite output is strange.

This problem occurs when the Bluetooth controller connects or disconnects.

this image is normal~! do not connects and disconnects.

problem occur~! did connects or disconnects.

this problem is…
In certain areas… The Sprite moves to an arbitrary position.
The logical location is normal. I checked.
Replacing the sprite will fix it.

i found~!
If the Bluetooth controller is connected or disconnected
cocos2dxActivicy::init is call~!
then new view and renderer are created.

I doubt this. But I want to ask before that.

What is the correct way to solve this problem?

Should I find a way not to change the renderer?
or Should I find a way to properly update the Sprite internals?

i solved it~!

The sprites that make the output strange are those that use the Pixel Shader.

if you use custom shader.
Reset shader when AppDelegate::applicationWillEnterForeground~!

Hello, I would like to use a bluetooth joystick in my game too, can you give me some help on how to do?

Hi JonathanReis.

my english is not good.
write with google translate.

A long time passed.
I need to look at the code to get a detailed description.
I write down what I remember with my Version Control System.

i succeed only for android os.
cocos2d-x version is 3.10.

way 1

  • use “cocos2d\cocos\platform\android\libcocos2dx-with-controller”
  • i’m build failed… :frowning:
  • close

way 2

  • sdk version 16 over

  • move some java code to “cocos2d\cocos\platform\android\java\src\org\cocos2dx\lib”

  • java code is located to “cocos2d\cocos\platform\android\ControllerManualAdapter\src\org\cocos2dx\lib”

    • “GameControllerActivity.java”
    • “GameControllerHelper.java”
    • “inputmanagercompat” Folder
  • modify “AppActivity.java”

    • extends GameControllerActivity
  • modify “GameControllerActivity.java”

    • i’m support “Standard” controller
    • remove all about “NIBIRU” “MOGA” “OUYA”
  • some JNI Problem from…

    • “cocos2d\cocos\platform\android\java\src\org\cocos2dx\lib”
    • “GameControllerAdapter.java”
      • private static native void nativeControllerConnected( … );
      • private static native void nativeControllerDisconnected( … );
      • private static native void nativeControllerButtonEvent( … );
      • private static native void nativeControllerAxisEvent( … );
    • native call is failed and crash
    • need fix that
  • JNI Fix with bypass

    • “proj.android\jni\hellocpp”
    • “main.cpp”
      • #include “base/CCController.h”
      • move and modify some code “CCController-android.cpp” to “main.cpp”
        • extern “C” {
          JNIEXPORT void JNICALL Java_org_cocos2dx_lib_GameControllerAdapter_nativeControllerConnected( JNIEnv* env, jobject thiz, jstring deviceName, jint controllerID ){
          nativeControllerConnected( env, thiz, deviceName, controllerID );
          }
          JNIEXPORT void JNICALL Java_org_cocos2dx_lib_GameControllerAdapter_nativeControllerDisconnected( JNIEnv* env, jobject thiz, jstring deviceName, jint controllerID ){
          nativeControllerDisconnected( env, thiz, deviceName, controllerID );
          }
          JNIEXPORT void JNICALL Java_org_cocos2dx_lib_GameControllerAdapter_nativeControllerButtonEvent( JNIEnv* env, jobject thiz, jstring deviceName, jint controllerID, jint button, jboolean isPressed, jfloat value, jboolean isAnalog ){
          nativeControllerButtonEvent( env, thiz, deviceName, controllerID, button, isPressed, value, isAnalog );
          }
          JNIEXPORT void JNICALL Java_org_cocos2dx_lib_GameControllerAdapter_nativeControllerAxisEvent( JNIEnv* env, jobject thiz, jstring deviceName, jint controllerID, jint axis, jfloat value, jboolean isAnalog ){
          nativeControllerAxisEvent( env, thiz, deviceName, controllerID, axis, value, isAnalog );
          }
          }
  • “CCController.h”

    • add
    • #if ( CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
      #include “jni/JniHelper.h”
      void nativeControllerConnected( JNIEnv* env, jobject thiz, jstring deviceName, jint controllerID );
      void nativeControllerDisconnected( JNIEnv* env, jobject thiz, jstring deviceName, jint controllerID );
      void nativeControllerButtonEvent( JNIEnv* env, jobject thiz, jstring deviceName, jint controllerID, jint button, jboolean isPressed, jfloat value, jboolean isAnalog );
      void nativeControllerAxisEvent( JNIEnv* env, jobject thiz, jstring deviceName, jint controllerID, jint axis, jfloat value, jboolean isAnalog );
      #endif
  • “CCController-android.cpp”

    • add
      • void nativeControllerConnected( JNIEnv* env, jobject thiz, jstring deviceName, jint controllerID ){
        cocos2d::ControllerImpl::onConnected( cocos2d::JniHelper::jstring2string( deviceName ), controllerID );
        }
        void nativeControllerDisconnected( JNIEnv* env, jobject thiz, jstring deviceName, jint controllerID ){
        cocos2d::ControllerImpl::onDisconnected( cocos2d::JniHelper::jstring2string( deviceName ), controllerID );
        }
        void nativeControllerButtonEvent( JNIEnv* env, jobject thiz, jstring deviceName, jint controllerID, jint button, jboolean isPressed, jfloat value, jboolean isAnalog ){
        cocos2d::ControllerImpl::onButtonEvent( cocos2d::JniHelper::jstring2string( deviceName ), controllerID, button, isPressed, value, isAnalog );
        }
        void nativeControllerAxisEvent( JNIEnv* env, jobject thiz, jstring deviceName, jint controllerID, jint axis, jfloat value, jboolean isAnalog ){
        cocos2d::ControllerImpl::onAxisEvent( cocos2d::JniHelper::jstring2string( deviceName ), controllerID, axis, value, isAnalog );
        }

make your controller with “CCEventListenerContrlller.h”

  • auto eventListener = cocos2d::EventListenerController::create();
  • getEventDispatcher()->addEventListenerWithSceneGraphPriority( eventListener, this );

I with your success. :slight_smile:

1 Like

I am waiting for my iPega joystick and the receiver for the xbox control to arrive and I will do the tests, when everything works I post here.

Thank you my friend.

1 Like

It worked, it was very good with iPega 9068 and xbox 360 with wireless receiver and OTG cable, if anyone needs:

cocos2d-x-3.15.1

Copy from:
/cocos2d/cocos/platform/android/ControllerManualAdapter/src/org/cocos2dx/lib

to:
/cocos2d/cocos/platform/android/java/src/org/cocos2dx/lib

Copy from:
/cocos2d/cocos/platform/android/ControllerManualAdapter/libs

to:
/cocos2d/cocos/platform/android/java/libs

Modify AppActivity.java:

//import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.lib.GameControllerActivity;

//public class AppActivity extends Cocos2dxActivity

public class AppActivity extends GameControllerActivity {
}

Scene_Game.h:

//Controle Joystick
#include “base/CCGameController.h”

public:
//Controle Joystick
void onKeyDown(cocos2d::Controller* controller, int keyCode, cocos2d::Event* event);
void onKeyUp(cocos2d::Controller* controller, int keyCode, cocos2d::Event* event);
void onAxisEvent(cocos2d::Controller* controller, int keyCode, cocos2d::Event* event);
void onConnectController(Controller* controller, Event* event);
void onDisconnectedController(Controller* controller, Event* event);

Scene_Game.cpp:

auto controllerListener = EventListenerController::create();

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

_eventDispatcher->addEventListenerWithSceneGraphPriority(controllerListener, this);

Controller::startDiscoveryController();

void Scene_Game::onConnectController(Controller* controller, Event* event)
{}

void Scene_Game::onDisconnectedController(Controller* controller, Event* event)
{}

void Scene_Game::onKeyDown(cocos2d::Controller *controller, int keyCode, cocos2d::Event *event)
{}

void Scene_Game::onKeyUp(cocos2d::Controller *controller, int keyCode, cocos2d::Event *event)
{}

void Scene_Game::onAxisEvent(cocos2d::Controller* controller, int keyCode, cocos2d::Event* event)
{}

Thanks @HyunminRyu

1 Like

Wow, thanks a lot! Great solution. :smiley:

I’m using 3.17 and the problem still happened.

1 Like

Yes we haven’t changed controller support in a while.

Yes, I understand physical controllers are far from being a priority right now, but it would be great if they could get more love at some point (specially in Windows, because I love Cocos2d-x and don’t intend to stop using it too early :smiley: )

The problem solved by Hyunmin is in CCController-android.cpp and only happens in run time, so it’s hard to catch. The 4 methods declared as “extern C” can’t be found by JNI, meaning any controller event will crash your app. This C/C++/Java binding thing really blows my mind, so I didn’t gave much time to it after this solution worked, but I’d guess this is probably due to the missing “JNIEXPORT void JNICALL” declarations. The fact they’re private probably doesn’t help either.

(My previous game used v3.03, and this didn’t happen)

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.