Added joypad button override functionality to JS API.
This commit is contained in:
parent
f85f93c5bd
commit
af9b53ba75
|
@ -101,6 +101,11 @@ ColorScriptObject::~ColorScriptObject()
|
||||||
//---- Joypad Object
|
//---- Joypad Object
|
||||||
//----------------------------------------------------
|
//----------------------------------------------------
|
||||||
int JoypadScriptObject::numInstances = 0;
|
int JoypadScriptObject::numInstances = 0;
|
||||||
|
/* Joypad Override Logic True Table
|
||||||
|
11 - true 01 - pass-through (default)
|
||||||
|
00 - false 10 - invert */
|
||||||
|
uint8_t JoypadScriptObject::jsOverrideMask1[MAX_JOYPAD_PLAYERS]= { 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
|
uint8_t JoypadScriptObject::jsOverrideMask2[MAX_JOYPAD_PLAYERS]= { 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
JoypadScriptObject::JoypadScriptObject(int playerIdx, bool immediate)
|
JoypadScriptObject::JoypadScriptObject(int playerIdx, bool immediate)
|
||||||
: QObject()
|
: QObject()
|
||||||
|
@ -132,35 +137,51 @@ JoypadScriptObject::~JoypadScriptObject()
|
||||||
//printf("JoypadScriptObject %p Destructor: %i\n", this, numInstances);
|
//printf("JoypadScriptObject %p Destructor: %i\n", this, numInstances);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------
|
//----------------------------------------------------
|
||||||
|
uint8_t JoypadScriptObject::readOverride(int which, uint8_t joyl)
|
||||||
|
{
|
||||||
|
joyl = (joyl & jsOverrideMask1[which]) | (~joyl & jsOverrideMask2[which]);
|
||||||
|
jsOverrideMask1[which] = 0xFF;
|
||||||
|
jsOverrideMask2[which] = 0x00;
|
||||||
|
return joyl;
|
||||||
|
|
||||||
|
}
|
||||||
|
//----------------------------------------------------
|
||||||
void JoypadScriptObject::refreshData(bool immediate)
|
void JoypadScriptObject::refreshData(bool immediate)
|
||||||
{
|
{
|
||||||
|
uint8_t buttons = 0;
|
||||||
if (immediate)
|
if (immediate)
|
||||||
{
|
{
|
||||||
uint32_t gpData = GetGamepadPressedImmediate();
|
uint32_t gpData = GetGamepadPressedImmediate();
|
||||||
uint8_t buttons = gpData >> (player * 8);
|
buttons = gpData >> (player * 8);
|
||||||
|
|
||||||
a = (buttons & 0x01) ? true : false;
|
|
||||||
b = (buttons & 0x02) ? true : false;
|
|
||||||
select = (buttons & 0x04) ? true : false;
|
|
||||||
start = (buttons & 0x08) ? true : false;
|
|
||||||
up = (buttons & 0x10) ? true : false;
|
|
||||||
down = (buttons & 0x20) ? true : false;
|
|
||||||
left = (buttons & 0x40) ? true : false;
|
|
||||||
right = (buttons & 0x80) ? true : false;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint8_t buttons = joy[player];
|
buttons = joy[player];
|
||||||
|
|
||||||
a = (buttons & 0x01) ? true : false;
|
|
||||||
b = (buttons & 0x02) ? true : false;
|
|
||||||
select = (buttons & 0x04) ? true : false;
|
|
||||||
start = (buttons & 0x08) ? true : false;
|
|
||||||
up = (buttons & 0x10) ? true : false;
|
|
||||||
down = (buttons & 0x20) ? true : false;
|
|
||||||
left = (buttons & 0x40) ? true : false;
|
|
||||||
right = (buttons & 0x80) ? true : false;
|
|
||||||
}
|
}
|
||||||
|
prev = current;
|
||||||
|
|
||||||
|
current.buttonMask = buttons;
|
||||||
|
current._immediate = immediate;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------
|
||||||
|
bool JoypadScriptObject::getButton(enum Button b)
|
||||||
|
{
|
||||||
|
bool isPressed = false;
|
||||||
|
uint8_t mask = 0x01 << b;
|
||||||
|
|
||||||
|
//printf("mask=%08x buttons=%08x\n", mask, current.buttonMask);
|
||||||
|
isPressed = (current.buttonMask & mask) ? true : false;
|
||||||
|
return isPressed;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------
|
||||||
|
bool JoypadScriptObject::buttonChanged(enum Button b)
|
||||||
|
{
|
||||||
|
bool hasChanged = false;
|
||||||
|
uint8_t mask = 0x01 << b;
|
||||||
|
|
||||||
|
//printf("mask=%08x buttons=%08x\n", mask, current.buttonMask);
|
||||||
|
hasChanged = ((current.buttonMask ^ prev.buttonMask) & mask) ? true : false;
|
||||||
|
return hasChanged;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------
|
//----------------------------------------------------
|
||||||
//---- EMU State Object
|
//---- EMU State Object
|
||||||
|
@ -2610,4 +2631,9 @@ void QScriptDialog_t::logOutput(const QString& text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//----------------------------------------------------
|
//----------------------------------------------------
|
||||||
|
uint8_t FCEU_JSReadJoypad(int which, uint8_t joyl)
|
||||||
|
{
|
||||||
|
return JS::JoypadScriptObject::readOverride(which, joyl);
|
||||||
|
}
|
||||||
|
//----------------------------------------------------
|
||||||
#endif // __FCEU_QSCRIPT_ENABLE__
|
#endif // __FCEU_QSCRIPT_ENABLE__
|
||||||
|
|
|
@ -122,31 +122,160 @@ public:
|
||||||
~JoypadScriptObject();
|
~JoypadScriptObject();
|
||||||
|
|
||||||
static constexpr int MAX_JOYPAD_PLAYERS = 4;
|
static constexpr int MAX_JOYPAD_PLAYERS = 4;
|
||||||
|
|
||||||
|
enum Button
|
||||||
|
{
|
||||||
|
FIRST_BUTTON = 0,
|
||||||
|
A_BUTTON = FIRST_BUTTON,
|
||||||
|
B_BUTTON,
|
||||||
|
SELECT_BUTTON,
|
||||||
|
START_BUTTON,
|
||||||
|
UP_BUTTON,
|
||||||
|
DOWN_BUTTON,
|
||||||
|
LEFT_BUTTON,
|
||||||
|
RIGHT_BUTTON,
|
||||||
|
LAST_BUTTON = RIGHT_BUTTON,
|
||||||
|
END_BUTTON
|
||||||
|
};
|
||||||
|
Q_ENUM(Button);
|
||||||
|
|
||||||
|
// Joypad Override Function
|
||||||
|
static uint8_t readOverride(int which, uint8_t joyl);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool up = false;
|
// Joypad Override Bit Masks
|
||||||
bool down = false;
|
static uint8_t jsOverrideMask1[MAX_JOYPAD_PLAYERS];
|
||||||
bool left = false;
|
static uint8_t jsOverrideMask2[MAX_JOYPAD_PLAYERS];
|
||||||
bool right = false;
|
|
||||||
bool select = false;
|
struct buttonState
|
||||||
bool start = false;
|
{
|
||||||
bool a = false;
|
uint32_t buttonMask = 0;
|
||||||
bool b = false;
|
bool _immediate = false;
|
||||||
|
};
|
||||||
|
buttonState current;
|
||||||
|
buttonState prev;
|
||||||
|
|
||||||
int player = 0;
|
int player = 0;
|
||||||
static int numInstances;
|
static int numInstances;
|
||||||
|
|
||||||
|
static constexpr uint32_t ButtonMaskA = 0x01;
|
||||||
|
static constexpr uint32_t ButtonMaskB = 0x02;
|
||||||
|
static constexpr uint32_t ButtonMaskSelect = 0x04;
|
||||||
|
static constexpr uint32_t ButtonMaskStart = 0x08;
|
||||||
|
static constexpr uint32_t ButtonMaskUp = 0x10;
|
||||||
|
static constexpr uint32_t ButtonMaskDown = 0x20;
|
||||||
|
static constexpr uint32_t ButtonMaskLeft = 0x40;
|
||||||
|
static constexpr uint32_t ButtonMaskRight = 0x80;
|
||||||
|
|
||||||
|
template <uint32_t mask> bool isBitSet(uint32_t& byte)
|
||||||
|
{
|
||||||
|
return (byte & mask) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t mask> bool isChanged()
|
||||||
|
{
|
||||||
|
return ((current.buttonMask ^ prev.buttonMask) & mask) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t mask> void setButtonOverride(bool value)
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
jsOverrideMask1[player] |= mask;
|
||||||
|
jsOverrideMask2[player] |= mask;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jsOverrideMask1[player] &= ~mask;
|
||||||
|
jsOverrideMask2[player] &= ~mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t mask> void clearButtonOverride()
|
||||||
|
{
|
||||||
|
jsOverrideMask1[player] |= mask;
|
||||||
|
jsOverrideMask2[player] &= ~mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t mask> void invertButtonOverride()
|
||||||
|
{
|
||||||
|
jsOverrideMask1[player] &= ~mask;
|
||||||
|
jsOverrideMask2[player] |= mask;
|
||||||
|
}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
Q_INVOKABLE void refreshData(bool immediate = false);
|
Q_INVOKABLE void refreshData(bool immediate = false);
|
||||||
Q_INVOKABLE bool getUp(){ return up; }
|
|
||||||
Q_INVOKABLE bool getDown(){ return down; }
|
Q_INVOKABLE bool getUp(){ return isBitSet<ButtonMaskUp>(current.buttonMask); }
|
||||||
Q_INVOKABLE bool getLeft(){ return left; }
|
Q_INVOKABLE bool getDown(){ return isBitSet<ButtonMaskDown>(current.buttonMask); }
|
||||||
Q_INVOKABLE bool getRight(){ return right; }
|
Q_INVOKABLE bool getLeft(){ return isBitSet<ButtonMaskLeft>(current.buttonMask); }
|
||||||
Q_INVOKABLE bool getSelect(){ return select; }
|
Q_INVOKABLE bool getRight(){ return isBitSet<ButtonMaskRight>(current.buttonMask); }
|
||||||
Q_INVOKABLE bool getStart(){ return start; }
|
Q_INVOKABLE bool getSelect(){ return isBitSet<ButtonMaskSelect>(current.buttonMask); }
|
||||||
Q_INVOKABLE bool getA(){ return a; }
|
Q_INVOKABLE bool getStart(){ return isBitSet<ButtonMaskStart>(current.buttonMask); }
|
||||||
Q_INVOKABLE bool getB(){ return b; }
|
Q_INVOKABLE bool getA(){ return isBitSet<ButtonMaskA>(current.buttonMask); }
|
||||||
|
Q_INVOKABLE bool getB(){ return isBitSet<ButtonMaskB>(current.buttonMask); }
|
||||||
|
|
||||||
|
Q_INVOKABLE bool upChanged(){ return isChanged<ButtonMaskUp>(); }
|
||||||
|
Q_INVOKABLE bool downChanged(){ return isChanged<ButtonMaskDown>(); }
|
||||||
|
Q_INVOKABLE bool leftChanged(){ return isChanged<ButtonMaskLeft>(); }
|
||||||
|
Q_INVOKABLE bool rightChanged(){ return isChanged<ButtonMaskRight>(); }
|
||||||
|
Q_INVOKABLE bool selectChanged(){ return isChanged<ButtonMaskSelect>(); }
|
||||||
|
Q_INVOKABLE bool startChanged(){ return isChanged<ButtonMaskStart>(); }
|
||||||
|
Q_INVOKABLE bool aChanged(){ return isChanged<ButtonMaskA>(); }
|
||||||
|
Q_INVOKABLE bool bChanged(){ return isChanged<ButtonMaskB>(); }
|
||||||
|
|
||||||
|
Q_INVOKABLE bool isImmediate(){ return current._immediate; }
|
||||||
|
Q_INVOKABLE bool getButton(enum Button b);
|
||||||
|
Q_INVOKABLE bool buttonChanged(enum Button b);
|
||||||
|
Q_INVOKABLE bool stateChanged(){ return prev.buttonMask != current.buttonMask; }
|
||||||
|
Q_INVOKABLE void setState(int mask){ prev.buttonMask = current.buttonMask; current.buttonMask = mask; }
|
||||||
|
Q_INVOKABLE int getState(){ return current.buttonMask; }
|
||||||
Q_INVOKABLE int maxPlayers(){ return MAX_JOYPAD_PLAYERS; }
|
Q_INVOKABLE int maxPlayers(){ return MAX_JOYPAD_PLAYERS; }
|
||||||
Q_INVOKABLE int getPlayer(){ return player; }
|
Q_INVOKABLE int getPlayer(){ return player; }
|
||||||
Q_INVOKABLE void setPlayer(int newPlayerIdx){ player = newPlayerIdx; }
|
Q_INVOKABLE void setPlayer(int newPlayerIdx){ player = newPlayerIdx; }
|
||||||
|
|
||||||
|
Q_INVOKABLE void ovrdClearA(){ clearButtonOverride<ButtonMaskA>(); }
|
||||||
|
Q_INVOKABLE void ovrdClearB(){ clearButtonOverride<ButtonMaskB>(); }
|
||||||
|
Q_INVOKABLE void ovrdClearStart(){ clearButtonOverride<ButtonMaskStart>(); }
|
||||||
|
Q_INVOKABLE void ovrdClearSelect(){ clearButtonOverride<ButtonMaskSelect>(); }
|
||||||
|
Q_INVOKABLE void ovrdClearUp(){ clearButtonOverride<ButtonMaskUp>(); }
|
||||||
|
Q_INVOKABLE void ovrdClearDown(){ clearButtonOverride<ButtonMaskDown>(); }
|
||||||
|
Q_INVOKABLE void ovrdClearLeft(){ clearButtonOverride<ButtonMaskLeft>(); }
|
||||||
|
Q_INVOKABLE void ovrdClearRight(){ clearButtonOverride<ButtonMaskRight>(); }
|
||||||
|
Q_INVOKABLE void ovrdClear(){ ovrdReset(); }
|
||||||
|
|
||||||
|
Q_INVOKABLE void ovrdInvertA(){ invertButtonOverride<ButtonMaskA>(); }
|
||||||
|
Q_INVOKABLE void ovrdInvertB(){ invertButtonOverride<ButtonMaskB>(); }
|
||||||
|
Q_INVOKABLE void ovrdInvertStart(){ invertButtonOverride<ButtonMaskStart>(); }
|
||||||
|
Q_INVOKABLE void ovrdInvertSelect(){ invertButtonOverride<ButtonMaskSelect>(); }
|
||||||
|
Q_INVOKABLE void ovrdInvertUp(){ invertButtonOverride<ButtonMaskUp>(); }
|
||||||
|
Q_INVOKABLE void ovrdInvertDown(){ invertButtonOverride<ButtonMaskDown>(); }
|
||||||
|
Q_INVOKABLE void ovrdInvertLeft(){ invertButtonOverride<ButtonMaskLeft>(); }
|
||||||
|
Q_INVOKABLE void ovrdInvertRight(){ invertButtonOverride<ButtonMaskRight>(); }
|
||||||
|
|
||||||
|
Q_INVOKABLE void ovrdA(bool value){ setButtonOverride<ButtonMaskA>(value); }
|
||||||
|
Q_INVOKABLE void ovrdB(bool value){ setButtonOverride<ButtonMaskB>(value); }
|
||||||
|
Q_INVOKABLE void ovrdStart(bool value){ setButtonOverride<ButtonMaskStart>(value); }
|
||||||
|
Q_INVOKABLE void ovrdSelect(bool value){ setButtonOverride<ButtonMaskSelect>(value); }
|
||||||
|
Q_INVOKABLE void ovrdUp(bool value){ setButtonOverride<ButtonMaskUp>(value); }
|
||||||
|
Q_INVOKABLE void ovrdDown(bool value){ setButtonOverride<ButtonMaskDown>(value); }
|
||||||
|
Q_INVOKABLE void ovrdLeft(bool value){ setButtonOverride<ButtonMaskLeft>(value); }
|
||||||
|
Q_INVOKABLE void ovrdRight(bool value){ setButtonOverride<ButtonMaskRight>(value); }
|
||||||
|
|
||||||
|
Q_INVOKABLE void ovrdReset()
|
||||||
|
{
|
||||||
|
jsOverrideMask1[player] = 0xFF;
|
||||||
|
jsOverrideMask2[player] = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_INVOKABLE void ovrdResetAll()
|
||||||
|
{
|
||||||
|
for (int i=0; i<MAX_JOYPAD_PLAYERS; i++)
|
||||||
|
{
|
||||||
|
jsOverrideMask1[i] = 0xFF;
|
||||||
|
jsOverrideMask2[i] = 0x00;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class EmuStateScriptObject: public QObject
|
class EmuStateScriptObject: public QObject
|
||||||
|
@ -574,11 +703,6 @@ private slots:
|
||||||
void stopScript(void);
|
void stopScript(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Formatted print
|
uint8_t FCEU_JSReadJoypad(int which, uint8_t phyState);
|
||||||
//int LuaPrintfToWindowConsole( __FCEU_PRINTF_FORMAT const char *format, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 2 );
|
|
||||||
|
|
||||||
//void PrintToWindowConsole(intptr_t hDlgAsInt, const char *str);
|
|
||||||
|
|
||||||
//int LuaKillMessageBox(void);
|
|
||||||
|
|
||||||
#endif // __FCEU_QSCRIPT_ENABLE__
|
#endif // __FCEU_QSCRIPT_ENABLE__
|
||||||
|
|
|
@ -234,6 +234,10 @@ static uint8 ReadGPVS(int w)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __FCEU_QSCRIPT_ENABLE__
|
||||||
|
extern uint8_t FCEU_JSReadJoypad(int which, uint8_t phyState);
|
||||||
|
#endif
|
||||||
|
|
||||||
static void UpdateGP(int w, void *data, int arg)
|
static void UpdateGP(int w, void *data, int arg)
|
||||||
{
|
{
|
||||||
if(w==0) //adelikat, 3/14/09: Changing the joypads to inclusive OR the user's joypad + the Lua joypad, this way lua only takes over the buttons it explicity says to
|
if(w==0) //adelikat, 3/14/09: Changing the joypads to inclusive OR the user's joypad + the Lua joypad, this way lua only takes over the buttons it explicity says to
|
||||||
|
@ -247,6 +251,11 @@ static void UpdateGP(int w, void *data, int arg)
|
||||||
joy[0] = *(uint32 *)joyports[0].ptr;;
|
joy[0] = *(uint32 *)joyports[0].ptr;;
|
||||||
joy[2] = *(uint32 *)joyports[0].ptr >> 16;
|
joy[2] = *(uint32 *)joyports[0].ptr >> 16;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __FCEU_QSCRIPT_ENABLE__
|
||||||
|
joy[0]= FCEU_JSReadJoypad(0,joy[0]);
|
||||||
|
joy[2]= FCEU_JSReadJoypad(2,joy[2]);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -259,6 +268,11 @@ static void UpdateGP(int w, void *data, int arg)
|
||||||
joy[1] = *(uint32 *)joyports[1].ptr >> 8;
|
joy[1] = *(uint32 *)joyports[1].ptr >> 8;
|
||||||
joy[3] = *(uint32 *)joyports[1].ptr >> 24;
|
joy[3] = *(uint32 *)joyports[1].ptr >> 24;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __FCEU_QSCRIPT_ENABLE__
|
||||||
|
joy[1]= FCEU_JSReadJoypad(1,joy[1]);
|
||||||
|
joy[3]= FCEU_JSReadJoypad(3,joy[3]);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue