mirror of
https://github.com/shadowfacts/jinput-arm64.git
synced 2025-12-06 08:01:59 +01:00
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:
parent
38d108b857
commit
df432c29ae
|
|
@ -24,7 +24,7 @@ public class RumbleTest {
|
||||||
Rumbler[] rumblers = controllers[i].getRumblers();
|
Rumbler[] rumblers = controllers[i].getRumblers();
|
||||||
System.out.println("Found " + rumblers.length + " rumblers");
|
System.out.println("Found " + rumblers.length + " rumblers");
|
||||||
for(int j=0;j<rumblers.length;j++) {
|
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);
|
System.out.println("Rumbling with intensity: " + 0.5f);
|
||||||
rumblers[j].rumble(0.5f);
|
rumblers[j].rumble(0.5f);
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,18 @@ public class LinuxDevice extends AbstractController {
|
||||||
components = (Component[]) axesArray.toArray(components);
|
components = (Component[]) axesArray.toArray(components);
|
||||||
|
|
||||||
guessType();
|
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(){
|
/*public Axis[] getAxes(){
|
||||||
|
|
@ -565,6 +577,13 @@ public class LinuxDevice extends AbstractController {
|
||||||
getNativeSupportedRelAxes(nativeID, 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
|
/** Native call to get the supported absolute axes for a device
|
||||||
* @param deviceID The native device number
|
* @param deviceID The native device number
|
||||||
* @param supportedAbsAxes aray to populate
|
* @param supportedAbsAxes aray to populate
|
||||||
|
|
@ -612,6 +631,12 @@ public class LinuxDevice extends AbstractController {
|
||||||
*/
|
*/
|
||||||
private native int getNativePortType(int deviceID);
|
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.
|
* A device that represents a joystick coolie hat.
|
||||||
* @author Jeremy Booth (jeremy@newdawnsoftware.com)
|
* @author Jeremy Booth (jeremy@newdawnsoftware.com)
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,8 @@ class Device {
|
||||||
virtual int getAbsAxisMinimum(int axisNumber) = 0;
|
virtual int getAbsAxisMinimum(int axisNumber) = 0;
|
||||||
virtual int getAbsAxisMaximum(int axisNumber) = 0;
|
virtual int getAbsAxisMaximum(int axisNumber) = 0;
|
||||||
virtual int getAbsAxisFuzz(int axisNumber) = 0;
|
virtual int getAbsAxisFuzz(int axisNumber) = 0;
|
||||||
|
virtual bool getFFEnabled() = 0;
|
||||||
|
virtual void rumble(float force) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //eventInterface_Device_h
|
#endif //eventInterface_Device_h
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,27 @@ EventDevice::EventDevice(char *deviceFileName) {
|
||||||
inited = 0;
|
inited = 0;
|
||||||
return;
|
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) {
|
if(ioctl(fd, EVIOCGNAME(sizeof(tempName)), tempName) < 0) {
|
||||||
|
|
@ -105,9 +126,7 @@ EventDevice::EventDevice(char *deviceFileName) {
|
||||||
numAbsAxes = 0;
|
numAbsAxes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(getBit(EV_FF, evtype_bitmask)) {
|
if(!getBit(EV_FF, evtype_bitmask)) {
|
||||||
ffSupported = 1;
|
|
||||||
} else {
|
|
||||||
ffSupported = 0;
|
ffSupported = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -382,3 +401,56 @@ int EventDevice::getAbsAxisMaximum(int axisNumber) {
|
||||||
int EventDevice::getAbsAxisFuzz(int axisNumber) {
|
int EventDevice::getAbsAxisFuzz(int axisNumber) {
|
||||||
return abs_features[axisNumber].fuzz;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,10 +56,14 @@ class EventDevice : public Device {
|
||||||
uint8_t key_bitmask[KEY_MAX/8 + 1];
|
uint8_t key_bitmask[KEY_MAX/8 + 1];
|
||||||
uint8_t rel_bitmask[REL_MAX/8 + 1];
|
uint8_t rel_bitmask[REL_MAX/8 + 1];
|
||||||
uint8_t abs_bitmask[ABS_MAX/8 + 1];
|
uint8_t abs_bitmask[ABS_MAX/8 + 1];
|
||||||
|
uint8_t ff_bitmask[16];
|
||||||
struct input_absinfo *abs_features;
|
struct input_absinfo *abs_features;
|
||||||
int absAxisLookup[ABS_MAX];
|
int absAxisLookup[ABS_MAX];
|
||||||
int relAxisLookup[REL_MAX];
|
int relAxisLookup[REL_MAX];
|
||||||
int buttonLookup[KEY_MAX];
|
int buttonLookup[KEY_MAX];
|
||||||
|
struct ff_effect effect;
|
||||||
|
struct input_event play, stop;
|
||||||
|
bool effect_playing;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EventDevice(char *deviceFilename);
|
EventDevice(char *deviceFilename);
|
||||||
|
|
@ -80,7 +84,8 @@ class EventDevice : public Device {
|
||||||
int getAbsAxisMaximum(int axisNumber);
|
int getAbsAxisMaximum(int axisNumber);
|
||||||
int getAbsAxisFuzz(int axisNumber);
|
int getAbsAxisFuzz(int axisNumber);
|
||||||
int isValidDevice();
|
int isValidDevice();
|
||||||
|
bool getFFEnabled();
|
||||||
|
void rumble(float force);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //eventInterface_eventDevice_h
|
#endif //eventInterface_eventDevice_h
|
||||||
|
|
|
||||||
|
|
@ -186,3 +186,11 @@ int JoystickDevice::getAbsAxisMaximum(int axisNumber) {
|
||||||
int JoystickDevice::getAbsAxisFuzz(int axisNumber) {
|
int JoystickDevice::getAbsAxisFuzz(int axisNumber) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool JoystickDevice::getFFEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoystickDevice::rumble(float force) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,8 @@ class JoystickDevice : public Device {
|
||||||
int getAbsAxisMaximum(int axisNumber);
|
int getAbsAxisMaximum(int axisNumber);
|
||||||
int getAbsAxisFuzz(int axisNumber);
|
int getAbsAxisFuzz(int axisNumber);
|
||||||
int isValidDevice();
|
int isValidDevice();
|
||||||
|
bool getFFEnabled();
|
||||||
|
void rumble(float force);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //eventInterface_eventDevice_h
|
#endif //eventInterface_eventDevice_h
|
||||||
|
|
|
||||||
|
|
@ -113,3 +113,11 @@ int MixedDevice::getAbsAxisMaximum(int axisNumber) {
|
||||||
int MixedDevice::getAbsAxisFuzz(int axisNumber) {
|
int MixedDevice::getAbsAxisFuzz(int axisNumber) {
|
||||||
return joystickDevice->getAbsAxisFuzz(axisNumber);
|
return joystickDevice->getAbsAxisFuzz(axisNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MixedDevice::getFFEnabled() {
|
||||||
|
return eventDevice->getFFEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixedDevice::rumble(float force) {
|
||||||
|
eventDevice->rumble(force);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,8 @@ class MixedDevice : public Device {
|
||||||
int getAbsAxisMinimum(int axisNumber);
|
int getAbsAxisMinimum(int axisNumber);
|
||||||
int getAbsAxisMaximum(int axisNumber);
|
int getAbsAxisMaximum(int axisNumber);
|
||||||
int getAbsAxisFuzz(int axisNumber);
|
int getAbsAxisFuzz(int axisNumber);
|
||||||
|
bool getFFEnabled();
|
||||||
|
void rumble(float force);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //eventInterface_eventDevice_h
|
#endif //eventInterface_eventDevice_h
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include "net_java_games_input_LinuxDevice.h"
|
#include "net_java_games_input_LinuxDevice.h"
|
||||||
#include "net_java_games_input_LinuxEnvironmentPlugin.h"
|
#include "net_java_games_input_LinuxEnvironmentPlugin.h"
|
||||||
#include "net_java_games_input_LinuxKeyboard.h"
|
#include "net_java_games_input_LinuxKeyboard.h"
|
||||||
|
#include "net_java_games_input_LinuxDeviceRumbler.h"
|
||||||
|
|
||||||
#include "Device.h"
|
#include "Device.h"
|
||||||
#include "EventDevice.h"
|
#include "EventDevice.h"
|
||||||
|
|
@ -302,7 +303,7 @@ JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxDevice_getNativePortType
|
||||||
(JNIEnv *, jobject, jint deviceID) {
|
(JNIEnv *, jobject, jint deviceID) {
|
||||||
|
|
||||||
LOG_TRACE("Getting bus type for device %d\n", deviceID);
|
LOG_TRACE("Getting bus type for device %d\n", deviceID);
|
||||||
jinputDeviceList[deviceID]->getBusType();
|
return jinputDeviceList[deviceID]->getBusType();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inaccessible static: NO_RUMBLERS */
|
/* Inaccessible static: NO_RUMBLERS */
|
||||||
|
|
@ -357,5 +358,32 @@ JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxKeyboard_getNativePortType
|
||||||
(JNIEnv *, jobject, jint deviceID) {
|
(JNIEnv *, jobject, jint deviceID) {
|
||||||
|
|
||||||
LOG_TRACE("Getting bus type for keyboard device %d\n", 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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,14 @@ JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxDevice_getNativeAbsAxisMin
|
||||||
JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxDevice_getNativePortType
|
JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxDevice_getNativePortType
|
||||||
(JNIEnv *, jobject, jint);
|
(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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
Loading…
Reference in a new issue