/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.badlogic.gdx.controllers.desktop.ois;
/** @author mzechner
* @author Nathan Sweet */
public class OisJoystick {
static private final int MIN_AXIS = -32768, MAX_AXIS = 32767;
static public enum OisPov {
Centered, North, South, East, West, NorthEast, SouthEast, NorthWest, SouthWest
}
private final String name;
private final long joystickPtr;
private final boolean[] buttons;
private final float[] axes;
private final int[] povs;
private final boolean[] slidersX, slidersY;
private OisListener listener;
public OisJoystick (long joystickPtr, String name) {
this.joystickPtr = joystickPtr;
this.name = name;
initialize(this);
buttons = new boolean[getButtonCount()];
axes = new float[getAxisCount()];
povs = new int[getPovCount()];
slidersX = new boolean[getSliderCount()];
slidersY = new boolean[getSliderCount()];
}
public void setListener (OisListener listener) {
this.listener = listener;
}
private void buttonPressed (int buttonIndex) {
buttons[buttonIndex] = true;
if (listener != null) listener.buttonPressed(this, buttonIndex);
}
private void buttonReleased (int buttonIndex) {
buttons[buttonIndex] = false;
if (listener != null) listener.buttonReleased(this, buttonIndex);
}
private void axisMoved (int axisIndex, int value) {
axes[axisIndex] = ((value - MIN_AXIS) << 1) / (float)(MAX_AXIS - MIN_AXIS) - 1; // -1 to 1
if (listener != null) listener.axisMoved(this, axisIndex, axes[axisIndex]);
}
private void povMoved (int povIndex, int value) {
povs[povIndex] = value;
if (listener != null) listener.povMoved(this, povIndex, getPov(povIndex));
}
private void sliderMoved (int sliderIndex, int x, int y) {
boolean xChanged = slidersX[sliderIndex] != (x == 1);
boolean yChanged = slidersY[sliderIndex] != (y == 1);
slidersX[sliderIndex] = x == 1;
slidersY[sliderIndex] = y == 1;
if (listener != null) {
if (xChanged) listener.xSliderMoved(this, sliderIndex, x == 1);
if (yChanged) listener.ySliderMoved(this, sliderIndex, y == 1);
}
}
public void update () {
update(joystickPtr, this);
}
public int getAxisCount () {
return getAxesCount(joystickPtr);
}
public int getButtonCount () {
return getButtonCount(joystickPtr);
}
public int getPovCount () {
return getPovCount(joystickPtr);
}
public int getSliderCount () {
return getSliderCount(joystickPtr);
}
public float getAxis (int axisIndex) {
if (axisIndex < 0 || axisIndex >= axes.length) return 0;
return axes[axisIndex];
}
public OisPov getPov (int povIndex) {
if (povIndex < 0 || povIndex >= povs.length) return OisPov.Centered;
switch (povs[povIndex]) {
case 0x00000000:
return OisPov.Centered;
case 0x00000001:
return OisPov.North;
case 0x00000010:
return OisPov.South;
case 0x00000100:
return OisPov.East;
case 0x00001000:
return OisPov.West;
case 0x00000101:
return OisPov.NorthEast;
case 0x00000110:
return OisPov.SouthEast;
case 0x00001001:
return OisPov.NorthWest;
case 0x00001010:
return OisPov.SouthWest;
default:
throw new RuntimeException("Unexpected POV value reported by OIS: " + povs[povIndex]);
}
}
public boolean isButtonPressed (int buttonIndex) {
if (buttonIndex < 0 || buttonIndex >= buttons.length) return false;
return buttons[buttonIndex];
}
public boolean getSliderX (int sliderIndex) {
if (sliderIndex < 0 || sliderIndex >= slidersX.length) return false;
return slidersX[sliderIndex];
}
public boolean getSliderY (int sliderIndex) {
if (sliderIndex < 0 || sliderIndex >= slidersY.length) return false;
return slidersY[sliderIndex];
}
public String getName () {
return name;
}
public String toString () {
return name;
}
// @off
/*JNI
#include <OISJoyStick.h>
#include <OISInputManager.h>
static jclass callbackClass = 0;
static jmethodID povMovedId = 0;
static jmethodID axisMovedId = 0;
static jmethodID sliderMovedId = 0;
static jmethodID buttonPressedId = 0;
static jmethodID buttonReleasedId = 0;
static void initializeClasses(JNIEnv* env, jobject clazz) {
// we leak one global ref
if(callbackClass == 0) {
callbackClass = (jclass)env->NewGlobalRef(env->GetObjectClass(clazz));
povMovedId = env->GetMethodID(callbackClass, "povMoved", "(II)V");
axisMovedId = env->GetMethodID(callbackClass, "axisMoved", "(II)V");
sliderMovedId = env->GetMethodID(callbackClass, "sliderMoved", "(III)V");
buttonPressedId = env->GetMethodID(callbackClass, "buttonPressed", "(I)V");
buttonReleasedId = env->GetMethodID(callbackClass, "buttonReleased", "(I)V");
}
}
class Listener : public OIS::JoyStickListener {
public:
Listener(JNIEnv* env, jobject obj) {
this->env = env;
this->obj = obj;
}
JNIEnv* env;
jobject obj;
bool povMoved (const OIS::JoyStickEvent &event, int pov);
bool axisMoved (const OIS::JoyStickEvent &event, int axis);
bool sliderMoved (const OIS::JoyStickEvent &event, int sliderID);
bool buttonPressed (const OIS::JoyStickEvent &event, int button);
bool buttonReleased (const OIS::JoyStickEvent &event, int button);
};
bool Listener::buttonPressed (const OIS::JoyStickEvent &event, int buttonId) {
env->CallVoidMethod(obj, buttonPressedId, (jint)buttonId);
return true;
}
bool Listener::buttonReleased (const OIS::JoyStickEvent &event, int buttonId) {
env->CallVoidMethod(obj, buttonReleasedId, (jint)buttonId);
return true;
}
bool Listener::axisMoved (const OIS::JoyStickEvent &event, int axisId) {
env->CallVoidMethod(obj, axisMovedId, (jint)axisId, (jint)event.state.mAxes[axisId].abs);
return true;
}
bool Listener::povMoved (const OIS::JoyStickEvent &event, int povId) {
env->CallVoidMethod(obj, povMovedId, (jint)povId, (jint)event.state.mPOV[povId].direction);
return true;
}
bool Listener::sliderMoved (const OIS::JoyStickEvent &event, int sliderId) {
env->CallVoidMethod(obj, sliderMovedId, (jint)sliderId,
(jint)event.state.mSliders[sliderId].abX, (jint)event.state.mSliders[sliderId].abY);
return true;
}
*/
private native void initialize(OisJoystick joystick); /*
initializeClasses(env, joystick);
*/
private native void update(long joystickPtr, OisJoystick callback); /*
OIS::JoyStick* joystick = (OIS::JoyStick*)joystickPtr;
Listener listener(env, callback);
joystick->setEventCallback(&listener);
joystick->capture();
*/
private native int getAxesCount (long joystickPtr); /*
OIS::JoyStick* joystick = (OIS::JoyStick*)joystickPtr;
return joystick->getNumberOfComponents(OIS::OIS_Axis);
*/
private native int getButtonCount (long joystickPtr); /*
OIS::JoyStick* joystick = (OIS::JoyStick*)joystickPtr;
return joystick->getNumberOfComponents(OIS::OIS_Button);
*/
private native int getPovCount (long joystickPtr); /*
OIS::JoyStick* joystick = (OIS::JoyStick*)joystickPtr;
return joystick->getNumberOfComponents(OIS::OIS_POV);
*/
private native int getSliderCount (long joystickPtr); /*
OIS::JoyStick* joystick = (OIS::JoyStick*)joystickPtr;
return joystick->getNumberOfComponents(OIS::OIS_Slider);
*/
}