diff --git a/src/drivers/Qt/QtScriptManager.cpp b/src/drivers/Qt/QtScriptManager.cpp index ecdce6a5..7a483221 100644 --- a/src/drivers/Qt/QtScriptManager.cpp +++ b/src/drivers/Qt/QtScriptManager.cpp @@ -101,6 +101,11 @@ ColorScriptObject::~ColorScriptObject() //---- Joypad Object //---------------------------------------------------- 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) : QObject() @@ -132,35 +137,51 @@ JoypadScriptObject::~JoypadScriptObject() //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) { + uint8_t buttons = 0; if (immediate) { uint32_t gpData = GetGamepadPressedImmediate(); - uint8_t 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; + buttons = gpData >> (player * 8); } else { - uint8_t 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; + buttons = joy[player]; } + 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 @@ -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__ diff --git a/src/drivers/Qt/QtScriptManager.h b/src/drivers/Qt/QtScriptManager.h index dd7d0700..160d62da 100644 --- a/src/drivers/Qt/QtScriptManager.h +++ b/src/drivers/Qt/QtScriptManager.h @@ -122,31 +122,160 @@ public: ~JoypadScriptObject(); 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: - bool up = false; - bool down = false; - bool left = false; - bool right = false; - bool select = false; - bool start = false; - bool a = false; - bool b = false; + // Joypad Override Bit Masks + static uint8_t jsOverrideMask1[MAX_JOYPAD_PLAYERS]; + static uint8_t jsOverrideMask2[MAX_JOYPAD_PLAYERS]; + + struct buttonState + { + uint32_t buttonMask = 0; + bool _immediate = false; + }; + buttonState current; + buttonState prev; + int player = 0; 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 bool isBitSet(uint32_t& byte) + { + return (byte & mask) ? true : false; + } + + template bool isChanged() + { + return ((current.buttonMask ^ prev.buttonMask) & mask) ? true : false; + } + + template void setButtonOverride(bool value) + { + if (value) + { + jsOverrideMask1[player] |= mask; + jsOverrideMask2[player] |= mask; + } + else + { + jsOverrideMask1[player] &= ~mask; + jsOverrideMask2[player] &= ~mask; + } + } + + template void clearButtonOverride() + { + jsOverrideMask1[player] |= mask; + jsOverrideMask2[player] &= ~mask; + } + + template void invertButtonOverride() + { + jsOverrideMask1[player] &= ~mask; + jsOverrideMask2[player] |= mask; + } + public slots: Q_INVOKABLE void refreshData(bool immediate = false); - Q_INVOKABLE bool getUp(){ return up; } - Q_INVOKABLE bool getDown(){ return down; } - Q_INVOKABLE bool getLeft(){ return left; } - Q_INVOKABLE bool getRight(){ return right; } - Q_INVOKABLE bool getSelect(){ return select; } - Q_INVOKABLE bool getStart(){ return start; } - Q_INVOKABLE bool getA(){ return a; } - Q_INVOKABLE bool getB(){ return b; } + + Q_INVOKABLE bool getUp(){ return isBitSet(current.buttonMask); } + Q_INVOKABLE bool getDown(){ return isBitSet(current.buttonMask); } + Q_INVOKABLE bool getLeft(){ return isBitSet(current.buttonMask); } + Q_INVOKABLE bool getRight(){ return isBitSet(current.buttonMask); } + Q_INVOKABLE bool getSelect(){ return isBitSet(current.buttonMask); } + Q_INVOKABLE bool getStart(){ return isBitSet(current.buttonMask); } + Q_INVOKABLE bool getA(){ return isBitSet(current.buttonMask); } + Q_INVOKABLE bool getB(){ return isBitSet(current.buttonMask); } + + Q_INVOKABLE bool upChanged(){ return isChanged(); } + Q_INVOKABLE bool downChanged(){ return isChanged(); } + Q_INVOKABLE bool leftChanged(){ return isChanged(); } + Q_INVOKABLE bool rightChanged(){ return isChanged(); } + Q_INVOKABLE bool selectChanged(){ return isChanged(); } + Q_INVOKABLE bool startChanged(){ return isChanged(); } + Q_INVOKABLE bool aChanged(){ return isChanged(); } + Q_INVOKABLE bool bChanged(){ return isChanged(); } + + 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 getPlayer(){ return player; } Q_INVOKABLE void setPlayer(int newPlayerIdx){ player = newPlayerIdx; } + + Q_INVOKABLE void ovrdClearA(){ clearButtonOverride(); } + Q_INVOKABLE void ovrdClearB(){ clearButtonOverride(); } + Q_INVOKABLE void ovrdClearStart(){ clearButtonOverride(); } + Q_INVOKABLE void ovrdClearSelect(){ clearButtonOverride(); } + Q_INVOKABLE void ovrdClearUp(){ clearButtonOverride(); } + Q_INVOKABLE void ovrdClearDown(){ clearButtonOverride(); } + Q_INVOKABLE void ovrdClearLeft(){ clearButtonOverride(); } + Q_INVOKABLE void ovrdClearRight(){ clearButtonOverride(); } + Q_INVOKABLE void ovrdClear(){ ovrdReset(); } + + Q_INVOKABLE void ovrdInvertA(){ invertButtonOverride(); } + Q_INVOKABLE void ovrdInvertB(){ invertButtonOverride(); } + Q_INVOKABLE void ovrdInvertStart(){ invertButtonOverride(); } + Q_INVOKABLE void ovrdInvertSelect(){ invertButtonOverride(); } + Q_INVOKABLE void ovrdInvertUp(){ invertButtonOverride(); } + Q_INVOKABLE void ovrdInvertDown(){ invertButtonOverride(); } + Q_INVOKABLE void ovrdInvertLeft(){ invertButtonOverride(); } + Q_INVOKABLE void ovrdInvertRight(){ invertButtonOverride(); } + + Q_INVOKABLE void ovrdA(bool value){ setButtonOverride(value); } + Q_INVOKABLE void ovrdB(bool value){ setButtonOverride(value); } + Q_INVOKABLE void ovrdStart(bool value){ setButtonOverride(value); } + Q_INVOKABLE void ovrdSelect(bool value){ setButtonOverride(value); } + Q_INVOKABLE void ovrdUp(bool value){ setButtonOverride(value); } + Q_INVOKABLE void ovrdDown(bool value){ setButtonOverride(value); } + Q_INVOKABLE void ovrdLeft(bool value){ setButtonOverride(value); } + Q_INVOKABLE void ovrdRight(bool value){ setButtonOverride(value); } + + Q_INVOKABLE void ovrdReset() + { + jsOverrideMask1[player] = 0xFF; + jsOverrideMask2[player] = 0x00; + } + + Q_INVOKABLE void ovrdResetAll() + { + for (int i=0; i> 16; #endif + + #ifdef __FCEU_QSCRIPT_ENABLE__ + joy[0]= FCEU_JSReadJoypad(0,joy[0]); + joy[2]= FCEU_JSReadJoypad(2,joy[2]); + #endif } else { @@ -259,6 +268,11 @@ static void UpdateGP(int w, void *data, int arg) joy[1] = *(uint32 *)joyports[1].ptr >> 8; joy[3] = *(uint32 *)joyports[1].ptr >> 24; #endif + + #ifdef __FCEU_QSCRIPT_ENABLE__ + joy[1]= FCEU_JSReadJoypad(1,joy[1]); + joy[3]= FCEU_JSReadJoypad(3,joy[3]); + #endif } }