Linux rumbler support

IT DOES NOT WORK YET though.

I'm in contact with the kernel module developers as I think it's a kernel bug
This commit is contained in:
endolf 2005-07-03 20:05:34 +00:00
parent 38d108b857
commit df432c29ae
12 changed files with 188 additions and 10 deletions

View file

@ -24,7 +24,7 @@ public class RumbleTest {
Rumbler[] rumblers = controllers[i].getRumblers();
System.out.println("Found " + rumblers.length + " rumblers");
for(int j=0;j<rumblers.length;j++) {
System.out.println("Rumbler " + rumblers[j].getAxisName() + " on axis " + rumblers[j].getAxisIdentifier().getName());
System.out.println("Rumbler " + rumblers[j].getAxisName() + " on axis " + rumblers[j].getAxisIdentifier());
System.out.println("Rumbling with intensity: " + 0.5f);
rumblers[j].rumble(0.5f);
try {

View file

@ -176,6 +176,18 @@ public class LinuxDevice extends AbstractController {
components = (Component[]) axesArray.toArray(components);
guessType();
if(getFFEnabled()) {
System.out.println("Java code thinks FF is enabled for device " + name);
Rumbler[] tempRumblers = rumblers;
rumblers = new Rumbler[rumblers.length+1];
System.arraycopy(tempRumblers,0,rumblers,0,tempRumblers.length);
rumblers[rumblers.length-1] = new LinuxDeviceRumbler(nativeID);
System.out.println("rumblers.length: " + rumblers.length);
System.out.println("getRumblers().length: " + getRumblers().length);
} else {
System.out.println("Java code thinks FF is disabled for device " + name);
}
}
/*public Axis[] getAxes(){
@ -564,6 +576,13 @@ public class LinuxDevice extends AbstractController {
private void getSupportedRelAxes(int supportedRelAxes[]) {
getNativeSupportedRelAxes(nativeID, supportedRelAxes);
}
/** Returns the status of FF support for this device
*
*/
private boolean getFFEnabled() {
return getNativeFFEnabled(nativeID);
}
/** Native call to get the supported absolute axes for a device
* @param deviceID The native device number
@ -611,6 +630,12 @@ public class LinuxDevice extends AbstractController {
* @return The port type
*/
private native int getNativePortType(int deviceID);
/** Gets the status of FF support for this device
* @param deviceID The device to get the port type for
* @return The port type
*/
private native boolean getNativeFFEnabled(int deviceID);
/**
* A device that represents a joystick coolie hat.

View file

@ -64,6 +64,8 @@ class Device {
virtual int getAbsAxisMinimum(int axisNumber) = 0;
virtual int getAbsAxisMaximum(int axisNumber) = 0;
virtual int getAbsAxisFuzz(int axisNumber) = 0;
virtual bool getFFEnabled() = 0;
virtual void rumble(float force) = 0;
};
#endif //eventInterface_Device_h

View file

@ -46,7 +46,7 @@ EventDevice::EventDevice(char *deviceFileName) {
char errorMessage[512];
sprintf(errorMessage, "Error opening device %s read/write, Force Feedback disabled for this device\n", deviceFileName);
perror(errorMessage);
fd = open(deviceFileName, O_RDONLY | O_NONBLOCK);
if(fd<0) {
/*char errorMessage[512];
@ -55,6 +55,27 @@ EventDevice::EventDevice(char *deviceFileName) {
inited = 0;
return;
}
} else {
if(ioctl(fd, EVIOCGBIT(EV_FF, sizeof(ff_bitmask)), ff_bitmask) < 0) {
char errorMessage[512];
sprintf(errorMessage, "Error reading device %s\n", deviceFileName);
perror(errorMessage);
}
if(getBit(FF_RUMBLE, ff_bitmask)==1) {
ffSupported = 1;
//LOG_TRACE("Force feedback supported for %s\n", deviceFileName);
int n_effects = 0;
if (ioctl(fd, EVIOCGEFFECTS, &n_effects) == -1) {
char errorMessage[512];
sprintf(errorMessage, "Failed to get number of effects for device %s\n", deviceFileName);
perror(errorMessage);
}
LOG_TRACE("Device %s supports %d simultanious effects\n", deviceFileName, n_effects);
effect_playing = false;
} else {
ffSupported = 0;
LOG_TRACE("Force feedback not supported for %s %d\n", deviceFileName, getBit(FF_RUMBLE, ff_bitmask));
}
}
if(ioctl(fd, EVIOCGNAME(sizeof(tempName)), tempName) < 0) {
@ -105,9 +126,7 @@ EventDevice::EventDevice(char *deviceFileName) {
numAbsAxes = 0;
}
if(getBit(EV_FF, evtype_bitmask)) {
ffSupported = 1;
} else {
if(!getBit(EV_FF, evtype_bitmask)) {
ffSupported = 0;
}
@ -382,3 +401,56 @@ int EventDevice::getAbsAxisMaximum(int axisNumber) {
int EventDevice::getAbsAxisFuzz(int axisNumber) {
return abs_features[axisNumber].fuzz;
}
bool EventDevice::getFFEnabled() {
if(ffSupported==1) {
//LOG_TRACE("FF is supported for %s\n", getName());
return true;
}
//LOG_TRACE("FF is not supported for %s\n", getName());
return false;
}
void EventDevice::rumble(float force) {
if(force>1) force=1;
if(force<-1) force=-1;
LOG_TRACE("Rumbling at %d%%, (shh, pretend)\n", (int)(force*100));
if(effect_playing==true) {
stop.type=EV_FF;
stop.code = effect.id;
stop.value=0;
if (ioctl(fd, EVIOCRMFF, effect.id) == -1) {
perror("Remove effect");
}
}
effect.type=FF_RUMBLE;
effect.id=-1;
effect.u.rumble.strong_magnitude = (int)(0x8000*force);
effect.u.rumble.weak_magnitude = (int)(0xc000*force);
effect.replay.length = 5000;
effect.replay.delay = 0;
if (ioctl(fd, EVIOCSFF, &effect) == -1) {
perror("Upload effect");
}
play.type = EV_FF;
play.code=effect.id;
play.value=1;
if(effect_playing==true) {
if (write(fd, (const void*) &stop, sizeof(stop)) == -1) {
perror("Failed to stop effect");
}
}
if (write(fd, (const void*) &play, sizeof(play)) == -1) {
perror("Failed to play effect");
} else {
effect_playing=true;
}
}

View file

@ -56,10 +56,14 @@ class EventDevice : public Device {
uint8_t key_bitmask[KEY_MAX/8 + 1];
uint8_t rel_bitmask[REL_MAX/8 + 1];
uint8_t abs_bitmask[ABS_MAX/8 + 1];
uint8_t ff_bitmask[16];
struct input_absinfo *abs_features;
int absAxisLookup[ABS_MAX];
int relAxisLookup[REL_MAX];
int buttonLookup[KEY_MAX];
struct ff_effect effect;
struct input_event play, stop;
bool effect_playing;
public:
EventDevice(char *deviceFilename);
@ -80,7 +84,8 @@ class EventDevice : public Device {
int getAbsAxisMaximum(int axisNumber);
int getAbsAxisFuzz(int axisNumber);
int isValidDevice();
bool getFFEnabled();
void rumble(float force);
};
#endif //eventInterface_eventDevice_h

View file

@ -186,3 +186,11 @@ int JoystickDevice::getAbsAxisMaximum(int axisNumber) {
int JoystickDevice::getAbsAxisFuzz(int axisNumber) {
return 0;
}
bool JoystickDevice::getFFEnabled() {
return false;
}
void JoystickDevice::rumble(float force) {
return;
}

View file

@ -62,7 +62,8 @@ class JoystickDevice : public Device {
int getAbsAxisMaximum(int axisNumber);
int getAbsAxisFuzz(int axisNumber);
int isValidDevice();
bool getFFEnabled();
void rumble(float force);
};
#endif //eventInterface_eventDevice_h

View file

@ -113,3 +113,11 @@ int MixedDevice::getAbsAxisMaximum(int axisNumber) {
int MixedDevice::getAbsAxisFuzz(int axisNumber) {
return joystickDevice->getAbsAxisFuzz(axisNumber);
}
bool MixedDevice::getFFEnabled() {
return eventDevice->getFFEnabled();
}
void MixedDevice::rumble(float force) {
eventDevice->rumble(force);
}

View file

@ -62,7 +62,8 @@ class MixedDevice : public Device {
int getAbsAxisMinimum(int axisNumber);
int getAbsAxisMaximum(int axisNumber);
int getAbsAxisFuzz(int axisNumber);
bool getFFEnabled();
void rumble(float force);
};
#endif //eventInterface_eventDevice_h

View file

@ -32,6 +32,7 @@
#include "net_java_games_input_LinuxDevice.h"
#include "net_java_games_input_LinuxEnvironmentPlugin.h"
#include "net_java_games_input_LinuxKeyboard.h"
#include "net_java_games_input_LinuxDeviceRumbler.h"
#include "Device.h"
#include "EventDevice.h"
@ -302,7 +303,7 @@ JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxDevice_getNativePortType
(JNIEnv *, jobject, jint deviceID) {
LOG_TRACE("Getting bus type for device %d\n", deviceID);
jinputDeviceList[deviceID]->getBusType();
return jinputDeviceList[deviceID]->getBusType();
}
/* Inaccessible static: NO_RUMBLERS */
@ -357,5 +358,32 @@ JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxKeyboard_getNativePortType
(JNIEnv *, jobject, jint deviceID) {
LOG_TRACE("Getting bus type for keyboard device %d\n", deviceID);
jinputDeviceList[deviceID]->getBusType();
return jinputDeviceList[deviceID]->getBusType();
}
/*
* Class: net_java_games_input_LinuxDevice
* Method: getFFEnabled
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL Java_net_java_games_input_LinuxDevice_getNativeFFEnabled
(JNIEnv *, jobject, jint deviceID) {
LOG_TRACE("Getting FFEnabled status for device %d\n", deviceID);
if(jinputDeviceList[deviceID]->getFFEnabled()) {
//LOG_TRACE("jinput lib thinks device %d is ff enabled\n", deviceID);
return JNI_TRUE;
}
//LOG_TRACE("jinput lib thinks device %d is ff disabled\n", deviceID);
return JNI_FALSE;
}
/*
* Class: net_java_games_input_LinuxRumblerDevice
* Method: nativeRumble
* Signature: (IF)V
*/
JNIEXPORT void JNICALL Java_net_java_games_input_LinuxDeviceRumbler_nativeRumble
(JNIEnv *, jobject, jint deviceID, jfloat force) {
jinputDeviceList[deviceID]->rumble(force);
}

View file

@ -73,6 +73,14 @@ JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxDevice_getNativeAbsAxisMin
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxDevice_getNativePortType
(JNIEnv *, jobject, jint);
/*
* Class: net_java_games_input_LinuxDevice
* Method: getFFEnabled
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL Java_net_java_games_input_LinuxDevice_getNativeFFEnabled
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}

View file

@ -0,0 +1,20 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class net_java_games_input_LinuxDeviceRumbler */
#ifndef _Included_net_java_games_input_LinuxDeviceRumbler
#define _Included_net_java_games_input_LinuxDeviceRumbler
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: net_java_games_input_LinuxDeviceRumbler
* Method: nativeRumble
* Signature: (IF)V
*/
JNIEXPORT void JNICALL Java_net_java_games_input_LinuxDeviceRumbler_nativeRumble
(JNIEnv *, jobject, jint, jfloat);
#ifdef __cplusplus
}
#endif
#endif