forked from bartvdbraak/blender
BGE Joystick Hat Bugfix
bug reported by blenderage on blenderartist (found other bugs too). - "All Hat Events" didnt work. - Multiple hats didnt work - use a menu with direction names rather then have the user guess. disallow zero as a direction. - Allow up to 4 hats (was 2). - Python api was clamping the axis to 2, maximum is currently JOYAXIS_MAX - 16 - New python attributes hatValues and hatSingle, match axis functions. - Use SDL Axis events to fill in the axis and hat array rather then filling in every axis with SDL_JoystickGetAxis for each axis event.
This commit is contained in:
parent
2a9d9605d0
commit
2fa8504dd1
@ -1534,13 +1534,14 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short
|
||||
else if (joy->type == SENS_JOY_HAT)
|
||||
{
|
||||
uiDefButI(block, NUM, 1, "Number:", xco+10, yco-68, 0.46 * (width-20), 19,
|
||||
&joy->hat, 1, 2.0, 100, 0,
|
||||
&joy->hat, 1, 4.0, 100, 0,
|
||||
"Specify which hat to use");
|
||||
|
||||
if ((joy->flag & SENS_JOY_ANY_EVENT)==0) {
|
||||
uiDefButI(block, NUM, 1, "Direction:", xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19,
|
||||
&joy->hatf, 0, 12, 100, 0,
|
||||
"Specify hat direction");
|
||||
str = "Direction%t|Up%x1|Down%x4|Left%x8|Right%x2|%l|Up/Right%x3|Down/Left%x12|Up/Left%x9|Down/Right%x6";
|
||||
uiDefButI(block, MENU, B_NOP, str, xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19,
|
||||
&joy->hatf, 2.0, 31, 0, 0,
|
||||
"The direction of the hat, use 'All Events' to recieve events on any direction");
|
||||
}
|
||||
}
|
||||
else { /* (joy->type == SENS_JOY_AXIS_SINGLE)*/
|
||||
@ -2752,12 +2753,12 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
|
||||
uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
|
||||
uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+40, yco-44, (width-80), 19, &(parAct->ob), "Set this object as parent");
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitI(block, TOGN, ACT_PARENT_COMPOUND, B_REDR,
|
||||
uiDefButBitS(block, TOGN, ACT_PARENT_COMPOUND, B_REDR,
|
||||
"Compound",
|
||||
xco + 40, yco - 64, (width - 80)/2, 19, &parAct->flag,
|
||||
0.0, 0.0, 0, 0,
|
||||
"Add this object shape to the parent shape (only if the parent shape is already compound)");
|
||||
uiDefButBitI(block, TOGN, ACT_PARENT_GHOST, B_REDR,
|
||||
uiDefButBitS(block, TOGN, ACT_PARENT_GHOST, B_REDR,
|
||||
"Ghost",
|
||||
xco + 40 + ((width - 80)/2), yco - 64, (width - 80)/2, 19, &parAct->flag,
|
||||
0.0, 0.0, 0, 0,
|
||||
|
@ -42,7 +42,6 @@ SCA_Joystick::SCA_Joystick(short int index)
|
||||
m_axismax(-1),
|
||||
m_buttonmax(-1),
|
||||
m_hatmax(-1),
|
||||
m_hatdir(-2),
|
||||
m_isinit(0),
|
||||
m_istrig_axis(0),
|
||||
m_istrig_button(0),
|
||||
@ -50,6 +49,10 @@ SCA_Joystick::SCA_Joystick(short int index)
|
||||
{
|
||||
for(int i=0; i<JOYAXIS_MAX; i++)
|
||||
m_axis_array[i]= 0;
|
||||
|
||||
for(int i=0; i<JOYHAT_MAX; i++)
|
||||
m_hat_array[i]= 0;
|
||||
|
||||
#ifndef DISABLE_SDL
|
||||
m_private = new PrivateData();
|
||||
#endif
|
||||
@ -184,20 +187,9 @@ bool SCA_Joystick::aButtonReleaseIsPositive(int button)
|
||||
}
|
||||
|
||||
|
||||
bool SCA_Joystick::aHatIsPositive(int dir)
|
||||
bool SCA_Joystick::aHatIsPositive(int hatnum, int dir)
|
||||
{
|
||||
bool result;
|
||||
int res = pGetHat(dir);
|
||||
res == dir? result = true : result = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
int SCA_Joystick::pGetHat(int direction)
|
||||
{
|
||||
if(direction == m_hatdir){
|
||||
return m_hatdir;
|
||||
}
|
||||
return 0;
|
||||
return (GetHat(hatnum)==dir) ? true : false;
|
||||
}
|
||||
|
||||
int SCA_Joystick::GetNumberOfAxes()
|
||||
@ -248,8 +240,11 @@ bool SCA_Joystick::CreateJoystickDevice(void)
|
||||
if (m_axismax > JOYAXIS_MAX) m_axismax= JOYAXIS_MAX; /* very unlikely */
|
||||
else if (m_axismax < 0) m_axismax = 0;
|
||||
|
||||
if (m_hatmax > JOYHAT_MAX) m_hatmax= JOYHAT_MAX; /* very unlikely */
|
||||
else if(m_hatmax<0) m_hatmax= 0;
|
||||
|
||||
if(m_buttonmax<0) m_buttonmax= 0;
|
||||
if(m_hatmax<0) m_hatmax= 0;
|
||||
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
@ -278,15 +273,6 @@ int SCA_Joystick::Connected(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SCA_Joystick::pFillAxes()
|
||||
{
|
||||
#ifndef DISABLE_SDL
|
||||
for(int i=0; i<m_axismax; i++)
|
||||
m_axis_array[i]= SDL_JoystickGetAxis(m_private->m_joystick, i);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int SCA_Joystick::pGetAxis(int axisnum, int udlr)
|
||||
{
|
||||
#ifndef DISABLE_SDL
|
||||
|
@ -53,28 +53,20 @@ class SCA_Joystick
|
||||
int m_joyindex;
|
||||
|
||||
/*
|
||||
*support for 2 axes
|
||||
*support for JOYAXIS_MAX axes (in pairs)
|
||||
*/
|
||||
int m_axis_array[JOYAXIS_MAX];
|
||||
|
||||
/*
|
||||
*support for JOYHAT_MAX hats (each is a direction)
|
||||
*/
|
||||
int m_hat_array[JOYHAT_MAX];
|
||||
|
||||
/*
|
||||
* Precision or range of the axes
|
||||
*/
|
||||
int m_prec;
|
||||
|
||||
/*
|
||||
* multiple axis values stored here
|
||||
*/
|
||||
int m_axisnum;
|
||||
int m_axisvalue;
|
||||
|
||||
/*
|
||||
* max # of axes avail
|
||||
*/
|
||||
/*disabled
|
||||
int m_axismax;
|
||||
*/
|
||||
|
||||
/*
|
||||
* button values stored here
|
||||
*/
|
||||
@ -88,18 +80,6 @@ class SCA_Joystick
|
||||
int m_buttonmax;
|
||||
int m_hatmax;
|
||||
|
||||
/*
|
||||
* hat values stored here
|
||||
*/
|
||||
int m_hatnum;
|
||||
int m_hatdir;
|
||||
|
||||
/*
|
||||
|
||||
* max # of hats avail
|
||||
disabled
|
||||
int m_hatmax;
|
||||
*/
|
||||
/* is the joystick initialized ?*/
|
||||
bool m_isinit;
|
||||
|
||||
@ -136,7 +116,6 @@ class SCA_Joystick
|
||||
/*
|
||||
* fills the axis mnember values
|
||||
*/
|
||||
void pFillAxes(void);
|
||||
void pFillButtons(void);
|
||||
|
||||
/*
|
||||
@ -149,11 +128,6 @@ class SCA_Joystick
|
||||
*/
|
||||
int pGetAxis(int axisnum, int udlr);
|
||||
|
||||
/*
|
||||
* gets the current hat direction
|
||||
*/
|
||||
int pGetHat(int direction);
|
||||
|
||||
SCA_Joystick(short int index);
|
||||
|
||||
~SCA_Joystick();
|
||||
@ -175,7 +149,7 @@ public:
|
||||
bool aAnyButtonReleaseIsPositive(void);
|
||||
bool aButtonPressIsPositive(int button);
|
||||
bool aButtonReleaseIsPositive(int button);
|
||||
bool aHatIsPositive(int dir);
|
||||
bool aHatIsPositive(int hatnum, int dir);
|
||||
|
||||
/*
|
||||
* precision is default '3200' which is overridden by input
|
||||
@ -191,8 +165,8 @@ public:
|
||||
return m_buttonnum;
|
||||
}
|
||||
|
||||
int GetHat(void){
|
||||
return m_hatdir;
|
||||
int GetHat(int index){
|
||||
return m_hat_array[index];
|
||||
}
|
||||
|
||||
int GetThreshold(void){
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
#define JOYINDEX_MAX 8
|
||||
#define JOYAXIS_MAX 16
|
||||
#define JOYHAT_MAX 4
|
||||
|
||||
#define JOYAXIS_RIGHT 0
|
||||
#define JOYAXIS_UP 1
|
||||
|
@ -35,17 +35,20 @@
|
||||
#ifndef DISABLE_SDL
|
||||
void SCA_Joystick::OnAxisMotion(SDL_Event* sdl_event)
|
||||
{
|
||||
pFillAxes();
|
||||
m_axisnum = sdl_event->jaxis.axis;
|
||||
m_axisvalue = sdl_event->jaxis.value;
|
||||
if(sdl_event->jaxis.axis >= JOYAXIS_MAX)
|
||||
return;
|
||||
|
||||
m_axis_array[sdl_event->jaxis.axis]= sdl_event->jaxis.value;
|
||||
m_istrig_axis = 1;
|
||||
}
|
||||
|
||||
|
||||
void SCA_Joystick::OnHatMotion(SDL_Event* sdl_event)
|
||||
{
|
||||
m_hatdir = sdl_event->jhat.value;
|
||||
m_hatnum = sdl_event->jhat.hat;
|
||||
if(sdl_event->jhat.hat >= JOYAXIS_MAX)
|
||||
return;
|
||||
|
||||
m_hat_array[sdl_event->jhat.hat]= sdl_event->jhat.value;
|
||||
m_istrig_hat = 1;
|
||||
}
|
||||
|
||||
|
@ -198,33 +198,20 @@ bool SCA_JoystickSensor::Evaluate()
|
||||
case KX_JOYSENSORMODE_HAT:
|
||||
{
|
||||
/* what is what!
|
||||
numberof = m_hat -- max 2
|
||||
numberof = m_hat -- max 4
|
||||
direction= m_hatf -- max 12
|
||||
*/
|
||||
|
||||
if (!js->IsTrigHat() && !reset) /* No events from SDL? - dont bother */
|
||||
return false;
|
||||
|
||||
if(m_hat == 1){
|
||||
if(js->aHatIsPositive(m_hatf)){
|
||||
m_istrig = 1;
|
||||
if((m_bAllEvents && js->GetHat(m_hat-1)) || js->aHatIsPositive(m_hat-1, m_hatf)) {
|
||||
m_istrig = 1;
|
||||
result = true;
|
||||
}else{
|
||||
if(m_istrig){
|
||||
m_istrig = 0;
|
||||
result = true;
|
||||
}else{
|
||||
if(m_istrig){
|
||||
m_istrig = 0;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(m_hat == 2){
|
||||
if(js->aHatIsPositive(m_hatf)){
|
||||
m_istrig = 1;
|
||||
result = true;
|
||||
}else{
|
||||
if(m_istrig){
|
||||
m_istrig = 0;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -331,6 +318,8 @@ PyAttributeDef SCA_JoystickSensor::Attributes[] = {
|
||||
KX_PYATTRIBUTE_INT_LIST_RW_CHECK("hat",0,12,true,SCA_JoystickSensor,m_hat,2,CheckHat),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("axisValues", SCA_JoystickSensor, pyattr_get_axis_values),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("axisSingle", SCA_JoystickSensor, pyattr_get_axis_single),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("hatValues", SCA_JoystickSensor, pyattr_get_hat_values),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("hatSingle", SCA_JoystickSensor, pyattr_get_hat_single),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("numAxis", SCA_JoystickSensor, pyattr_get_num_axis),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("numButtons", SCA_JoystickSensor, pyattr_get_num_buttons),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("numHats", SCA_JoystickSensor, pyattr_get_num_hats),
|
||||
@ -617,6 +606,29 @@ PyObject* SCA_JoystickSensor::pyattr_get_axis_single(void *self_v, const KX_PYAT
|
||||
return PyInt_FromLong(joy->GetAxisPosition(self->m_axis-1));
|
||||
}
|
||||
|
||||
PyObject* SCA_JoystickSensor::pyattr_get_hat_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
|
||||
SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex);
|
||||
|
||||
int hat_index= joy->GetNumberOfHats();
|
||||
PyObject *list= PyList_New(hat_index);
|
||||
|
||||
while(hat_index--) {
|
||||
PyList_SET_ITEM(list, hat_index, PyInt_FromLong(joy->GetHat(hat_index)));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
PyObject* SCA_JoystickSensor::pyattr_get_hat_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
|
||||
SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex);
|
||||
|
||||
return PyInt_FromLong(joy->GetHat(self->m_hat-1));
|
||||
}
|
||||
|
||||
PyObject* SCA_JoystickSensor::pyattr_get_num_axis(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
|
||||
|
@ -30,6 +30,7 @@
|
||||
#define __JOYSENSOR_H
|
||||
|
||||
#include "SCA_ISensor.h"
|
||||
#include "./Joystick/SCA_JoystickDefines.h"
|
||||
|
||||
class SCA_JoystickSensor :public SCA_ISensor
|
||||
{
|
||||
@ -37,7 +38,7 @@ class SCA_JoystickSensor :public SCA_ISensor
|
||||
class SCA_JoystickManager* m_pJoystickMgr;
|
||||
|
||||
/**
|
||||
* Axis 1-or-2, MUST be followed by m_axisf
|
||||
* Axis 1-JOYAXIS_MAX, MUST be followed by m_axisf
|
||||
*/
|
||||
int m_axis;
|
||||
/**
|
||||
@ -53,11 +54,11 @@ class SCA_JoystickSensor :public SCA_ISensor
|
||||
*/
|
||||
int m_buttonf;
|
||||
/**
|
||||
* The actual hat. MUST be followed by m_hatf
|
||||
* The actual hat 1-JOYHAT_MAX. MUST be followed by m_hatf
|
||||
*/
|
||||
int m_hat;
|
||||
/**
|
||||
* Flag to find direction 0-11, MUST be an int
|
||||
* Flag to find direction 1-12, MUST be an int
|
||||
*/
|
||||
int m_hatf;
|
||||
/**
|
||||
@ -152,6 +153,8 @@ public:
|
||||
|
||||
static PyObject* pyattr_get_axis_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_axis_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_hat_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_hat_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_num_axis(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_num_buttons(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_num_hats(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
@ -164,8 +167,8 @@ public:
|
||||
SCA_JoystickSensor* sensor = reinterpret_cast<SCA_JoystickSensor*>(self);
|
||||
if (sensor->m_axis < 1)
|
||||
sensor->m_axis = 1;
|
||||
else if (sensor->m_axis > 2)
|
||||
sensor->m_axis = 2;
|
||||
else if (sensor->m_axis > JOYAXIS_MAX)
|
||||
sensor->m_axis = JOYAXIS_MAX;
|
||||
return 0;
|
||||
}
|
||||
static int CheckHat(void *self, const PyAttributeDef*)
|
||||
@ -173,8 +176,8 @@ public:
|
||||
SCA_JoystickSensor* sensor = reinterpret_cast<SCA_JoystickSensor*>(self);
|
||||
if (sensor->m_hat < 1)
|
||||
sensor->m_hat = 1;
|
||||
else if (sensor->m_hat > 2)
|
||||
sensor->m_hat = 2;
|
||||
else if (sensor->m_hat > JOYHAT_MAX)
|
||||
sensor->m_hat = JOYHAT_MAX;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ class CValue(PyObjectPlus):
|
||||
This class is a basis for other classes.
|
||||
@ivar name: The name of this CValue derived object (read-only).
|
||||
@type name: string
|
||||
@group Deprecated: getName
|
||||
"""
|
||||
def getName():
|
||||
"""
|
||||
@ -259,7 +260,7 @@ class SCA_IController(SCA_ILogicBrick):
|
||||
@type actuators: sequence supporting index/string lookups and iteration.
|
||||
@ivar bookmark: the bookmark option.
|
||||
If set, the controller executes always before all other non-bookmarked controllers.
|
||||
- note: Order of execution between bookmarked controllers is not guaranteed.
|
||||
note: Order of execution between bookmarked controllers is not guaranteed.
|
||||
@type bookmark: bool
|
||||
"""
|
||||
#{ Deprecated
|
||||
@ -4741,6 +4742,24 @@ class SCA_JoystickSensor(SCA_ISensor):
|
||||
Only use this for "Single Axis" type sensors otherwise it will raise an error.
|
||||
@type axisSingle: int
|
||||
|
||||
@ivar hatValues: (read-only) The state of the joysticks hats as a list of values L{numHats} long.
|
||||
each spesifying the direction of the hat from 1 to 12, 0 when inactive.
|
||||
Hat directions are as follows...
|
||||
- 0:None
|
||||
- 1:Up
|
||||
- 2:Right
|
||||
- 4:Down
|
||||
- 8:Left
|
||||
- 3:Up - Right
|
||||
- 6:Down - Right
|
||||
- 12:Down - Left
|
||||
- 9:Up - Left
|
||||
|
||||
@type hatValues: list of ints
|
||||
|
||||
@ivar hatSingle: (read-only) like L{hatValues} but returns a single hat direction value that is set by the sensor.
|
||||
@type hatSingle: int
|
||||
|
||||
@ivar numAxis: (read-only) The number of axes for the joystick at this index.
|
||||
@type numAxis: integer
|
||||
@ivar numButtons: (read-only) The number of buttons for the joystick at this index.
|
||||
@ -4760,8 +4779,8 @@ class SCA_JoystickSensor(SCA_ISensor):
|
||||
axisDirection: 0=right, 1=up, 2=left, 3=down
|
||||
@type axis: [integer, integer]
|
||||
@ivar hat: The hat the sensor reacts to, as a list of two values: [hatIndex, hatDirection]
|
||||
hatIndex: the hat index to use when detecting hat movement, 1=primary hat, 2=secondary hat.
|
||||
hatDirection: 0-11
|
||||
hatIndex: the hat index to use when detecting hat movement, 1=primary hat, 2=secondary hat (4 max).
|
||||
hatDirection: 1-12
|
||||
@type hat: [integer, integer]
|
||||
"""
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user