Skip to content

Commit af9b53b

Browse files
committed
Added joypad button override functionality to JS API.
1 parent f85f93c commit af9b53b

File tree

3 files changed

+206
-42
lines changed

3 files changed

+206
-42
lines changed

src/drivers/Qt/QtScriptManager.cpp

+46-20
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,11 @@ ColorScriptObject::~ColorScriptObject()
101101
//---- Joypad Object
102102
//----------------------------------------------------
103103
int JoypadScriptObject::numInstances = 0;
104+
/* Joypad Override Logic True Table
105+
11 - true 01 - pass-through (default)
106+
00 - false 10 - invert */
107+
uint8_t JoypadScriptObject::jsOverrideMask1[MAX_JOYPAD_PLAYERS]= { 0xFF, 0xFF, 0xFF, 0xFF };
108+
uint8_t JoypadScriptObject::jsOverrideMask2[MAX_JOYPAD_PLAYERS]= { 0x00, 0x00, 0x00, 0x00 };
104109

105110
JoypadScriptObject::JoypadScriptObject(int playerIdx, bool immediate)
106111
: QObject()
@@ -132,35 +137,51 @@ JoypadScriptObject::~JoypadScriptObject()
132137
//printf("JoypadScriptObject %p Destructor: %i\n", this, numInstances);
133138
}
134139
//----------------------------------------------------
140+
uint8_t JoypadScriptObject::readOverride(int which, uint8_t joyl)
141+
{
142+
joyl = (joyl & jsOverrideMask1[which]) | (~joyl & jsOverrideMask2[which]);
143+
jsOverrideMask1[which] = 0xFF;
144+
jsOverrideMask2[which] = 0x00;
145+
return joyl;
146+
147+
}
148+
//----------------------------------------------------
135149
void JoypadScriptObject::refreshData(bool immediate)
136150
{
151+
uint8_t buttons = 0;
137152
if (immediate)
138153
{
139154
uint32_t gpData = GetGamepadPressedImmediate();
140-
uint8_t buttons = gpData >> (player * 8);
141-
142-
a = (buttons & 0x01) ? true : false;
143-
b = (buttons & 0x02) ? true : false;
144-
select = (buttons & 0x04) ? true : false;
145-
start = (buttons & 0x08) ? true : false;
146-
up = (buttons & 0x10) ? true : false;
147-
down = (buttons & 0x20) ? true : false;
148-
left = (buttons & 0x40) ? true : false;
149-
right = (buttons & 0x80) ? true : false;
155+
buttons = gpData >> (player * 8);
150156
}
151157
else
152158
{
153-
uint8_t buttons = joy[player];
154-
155-
a = (buttons & 0x01) ? true : false;
156-
b = (buttons & 0x02) ? true : false;
157-
select = (buttons & 0x04) ? true : false;
158-
start = (buttons & 0x08) ? true : false;
159-
up = (buttons & 0x10) ? true : false;
160-
down = (buttons & 0x20) ? true : false;
161-
left = (buttons & 0x40) ? true : false;
162-
right = (buttons & 0x80) ? true : false;
159+
buttons = joy[player];
163160
}
161+
prev = current;
162+
163+
current.buttonMask = buttons;
164+
current._immediate = immediate;
165+
}
166+
//----------------------------------------------------
167+
bool JoypadScriptObject::getButton(enum Button b)
168+
{
169+
bool isPressed = false;
170+
uint8_t mask = 0x01 << b;
171+
172+
//printf("mask=%08x buttons=%08x\n", mask, current.buttonMask);
173+
isPressed = (current.buttonMask & mask) ? true : false;
174+
return isPressed;
175+
}
176+
//----------------------------------------------------
177+
bool JoypadScriptObject::buttonChanged(enum Button b)
178+
{
179+
bool hasChanged = false;
180+
uint8_t mask = 0x01 << b;
181+
182+
//printf("mask=%08x buttons=%08x\n", mask, current.buttonMask);
183+
hasChanged = ((current.buttonMask ^ prev.buttonMask) & mask) ? true : false;
184+
return hasChanged;
164185
}
165186
//----------------------------------------------------
166187
//---- EMU State Object
@@ -2610,4 +2631,9 @@ void QScriptDialog_t::logOutput(const QString& text)
26102631
}
26112632
}
26122633
//----------------------------------------------------
2634+
uint8_t FCEU_JSReadJoypad(int which, uint8_t joyl)
2635+
{
2636+
return JS::JoypadScriptObject::readOverride(which, joyl);
2637+
}
2638+
//----------------------------------------------------
26132639
#endif // __FCEU_QSCRIPT_ENABLE__

src/drivers/Qt/QtScriptManager.h

+146-22
Original file line numberDiff line numberDiff line change
@@ -122,31 +122,160 @@ class JoypadScriptObject: public QObject
122122
~JoypadScriptObject();
123123

124124
static constexpr int MAX_JOYPAD_PLAYERS = 4;
125+
126+
enum Button
127+
{
128+
FIRST_BUTTON = 0,
129+
A_BUTTON = FIRST_BUTTON,
130+
B_BUTTON,
131+
SELECT_BUTTON,
132+
START_BUTTON,
133+
UP_BUTTON,
134+
DOWN_BUTTON,
135+
LEFT_BUTTON,
136+
RIGHT_BUTTON,
137+
LAST_BUTTON = RIGHT_BUTTON,
138+
END_BUTTON
139+
};
140+
Q_ENUM(Button);
141+
142+
// Joypad Override Function
143+
static uint8_t readOverride(int which, uint8_t joyl);
144+
125145
private:
126-
bool up = false;
127-
bool down = false;
128-
bool left = false;
129-
bool right = false;
130-
bool select = false;
131-
bool start = false;
132-
bool a = false;
133-
bool b = false;
146+
// Joypad Override Bit Masks
147+
static uint8_t jsOverrideMask1[MAX_JOYPAD_PLAYERS];
148+
static uint8_t jsOverrideMask2[MAX_JOYPAD_PLAYERS];
149+
150+
struct buttonState
151+
{
152+
uint32_t buttonMask = 0;
153+
bool _immediate = false;
154+
};
155+
buttonState current;
156+
buttonState prev;
157+
134158
int player = 0;
135159
static int numInstances;
136160

161+
static constexpr uint32_t ButtonMaskA = 0x01;
162+
static constexpr uint32_t ButtonMaskB = 0x02;
163+
static constexpr uint32_t ButtonMaskSelect = 0x04;
164+
static constexpr uint32_t ButtonMaskStart = 0x08;
165+
static constexpr uint32_t ButtonMaskUp = 0x10;
166+
static constexpr uint32_t ButtonMaskDown = 0x20;
167+
static constexpr uint32_t ButtonMaskLeft = 0x40;
168+
static constexpr uint32_t ButtonMaskRight = 0x80;
169+
170+
template <uint32_t mask> bool isBitSet(uint32_t& byte)
171+
{
172+
return (byte & mask) ? true : false;
173+
}
174+
175+
template <uint32_t mask> bool isChanged()
176+
{
177+
return ((current.buttonMask ^ prev.buttonMask) & mask) ? true : false;
178+
}
179+
180+
template <uint32_t mask> void setButtonOverride(bool value)
181+
{
182+
if (value)
183+
{
184+
jsOverrideMask1[player] |= mask;
185+
jsOverrideMask2[player] |= mask;
186+
}
187+
else
188+
{
189+
jsOverrideMask1[player] &= ~mask;
190+
jsOverrideMask2[player] &= ~mask;
191+
}
192+
}
193+
194+
template <uint32_t mask> void clearButtonOverride()
195+
{
196+
jsOverrideMask1[player] |= mask;
197+
jsOverrideMask2[player] &= ~mask;
198+
}
199+
200+
template <uint32_t mask> void invertButtonOverride()
201+
{
202+
jsOverrideMask1[player] &= ~mask;
203+
jsOverrideMask2[player] |= mask;
204+
}
205+
137206
public slots:
138207
Q_INVOKABLE void refreshData(bool immediate = false);
139-
Q_INVOKABLE bool getUp(){ return up; }
140-
Q_INVOKABLE bool getDown(){ return down; }
141-
Q_INVOKABLE bool getLeft(){ return left; }
142-
Q_INVOKABLE bool getRight(){ return right; }
143-
Q_INVOKABLE bool getSelect(){ return select; }
144-
Q_INVOKABLE bool getStart(){ return start; }
145-
Q_INVOKABLE bool getA(){ return a; }
146-
Q_INVOKABLE bool getB(){ return b; }
208+
209+
Q_INVOKABLE bool getUp(){ return isBitSet<ButtonMaskUp>(current.buttonMask); }
210+
Q_INVOKABLE bool getDown(){ return isBitSet<ButtonMaskDown>(current.buttonMask); }
211+
Q_INVOKABLE bool getLeft(){ return isBitSet<ButtonMaskLeft>(current.buttonMask); }
212+
Q_INVOKABLE bool getRight(){ return isBitSet<ButtonMaskRight>(current.buttonMask); }
213+
Q_INVOKABLE bool getSelect(){ return isBitSet<ButtonMaskSelect>(current.buttonMask); }
214+
Q_INVOKABLE bool getStart(){ return isBitSet<ButtonMaskStart>(current.buttonMask); }
215+
Q_INVOKABLE bool getA(){ return isBitSet<ButtonMaskA>(current.buttonMask); }
216+
Q_INVOKABLE bool getB(){ return isBitSet<ButtonMaskB>(current.buttonMask); }
217+
218+
Q_INVOKABLE bool upChanged(){ return isChanged<ButtonMaskUp>(); }
219+
Q_INVOKABLE bool downChanged(){ return isChanged<ButtonMaskDown>(); }
220+
Q_INVOKABLE bool leftChanged(){ return isChanged<ButtonMaskLeft>(); }
221+
Q_INVOKABLE bool rightChanged(){ return isChanged<ButtonMaskRight>(); }
222+
Q_INVOKABLE bool selectChanged(){ return isChanged<ButtonMaskSelect>(); }
223+
Q_INVOKABLE bool startChanged(){ return isChanged<ButtonMaskStart>(); }
224+
Q_INVOKABLE bool aChanged(){ return isChanged<ButtonMaskA>(); }
225+
Q_INVOKABLE bool bChanged(){ return isChanged<ButtonMaskB>(); }
226+
227+
Q_INVOKABLE bool isImmediate(){ return current._immediate; }
228+
Q_INVOKABLE bool getButton(enum Button b);
229+
Q_INVOKABLE bool buttonChanged(enum Button b);
230+
Q_INVOKABLE bool stateChanged(){ return prev.buttonMask != current.buttonMask; }
231+
Q_INVOKABLE void setState(int mask){ prev.buttonMask = current.buttonMask; current.buttonMask = mask; }
232+
Q_INVOKABLE int getState(){ return current.buttonMask; }
147233
Q_INVOKABLE int maxPlayers(){ return MAX_JOYPAD_PLAYERS; }
148234
Q_INVOKABLE int getPlayer(){ return player; }
149235
Q_INVOKABLE void setPlayer(int newPlayerIdx){ player = newPlayerIdx; }
236+
237+
Q_INVOKABLE void ovrdClearA(){ clearButtonOverride<ButtonMaskA>(); }
238+
Q_INVOKABLE void ovrdClearB(){ clearButtonOverride<ButtonMaskB>(); }
239+
Q_INVOKABLE void ovrdClearStart(){ clearButtonOverride<ButtonMaskStart>(); }
240+
Q_INVOKABLE void ovrdClearSelect(){ clearButtonOverride<ButtonMaskSelect>(); }
241+
Q_INVOKABLE void ovrdClearUp(){ clearButtonOverride<ButtonMaskUp>(); }
242+
Q_INVOKABLE void ovrdClearDown(){ clearButtonOverride<ButtonMaskDown>(); }
243+
Q_INVOKABLE void ovrdClearLeft(){ clearButtonOverride<ButtonMaskLeft>(); }
244+
Q_INVOKABLE void ovrdClearRight(){ clearButtonOverride<ButtonMaskRight>(); }
245+
Q_INVOKABLE void ovrdClear(){ ovrdReset(); }
246+
247+
Q_INVOKABLE void ovrdInvertA(){ invertButtonOverride<ButtonMaskA>(); }
248+
Q_INVOKABLE void ovrdInvertB(){ invertButtonOverride<ButtonMaskB>(); }
249+
Q_INVOKABLE void ovrdInvertStart(){ invertButtonOverride<ButtonMaskStart>(); }
250+
Q_INVOKABLE void ovrdInvertSelect(){ invertButtonOverride<ButtonMaskSelect>(); }
251+
Q_INVOKABLE void ovrdInvertUp(){ invertButtonOverride<ButtonMaskUp>(); }
252+
Q_INVOKABLE void ovrdInvertDown(){ invertButtonOverride<ButtonMaskDown>(); }
253+
Q_INVOKABLE void ovrdInvertLeft(){ invertButtonOverride<ButtonMaskLeft>(); }
254+
Q_INVOKABLE void ovrdInvertRight(){ invertButtonOverride<ButtonMaskRight>(); }
255+
256+
Q_INVOKABLE void ovrdA(bool value){ setButtonOverride<ButtonMaskA>(value); }
257+
Q_INVOKABLE void ovrdB(bool value){ setButtonOverride<ButtonMaskB>(value); }
258+
Q_INVOKABLE void ovrdStart(bool value){ setButtonOverride<ButtonMaskStart>(value); }
259+
Q_INVOKABLE void ovrdSelect(bool value){ setButtonOverride<ButtonMaskSelect>(value); }
260+
Q_INVOKABLE void ovrdUp(bool value){ setButtonOverride<ButtonMaskUp>(value); }
261+
Q_INVOKABLE void ovrdDown(bool value){ setButtonOverride<ButtonMaskDown>(value); }
262+
Q_INVOKABLE void ovrdLeft(bool value){ setButtonOverride<ButtonMaskLeft>(value); }
263+
Q_INVOKABLE void ovrdRight(bool value){ setButtonOverride<ButtonMaskRight>(value); }
264+
265+
Q_INVOKABLE void ovrdReset()
266+
{
267+
jsOverrideMask1[player] = 0xFF;
268+
jsOverrideMask2[player] = 0x00;
269+
}
270+
271+
Q_INVOKABLE void ovrdResetAll()
272+
{
273+
for (int i=0; i<MAX_JOYPAD_PLAYERS; i++)
274+
{
275+
jsOverrideMask1[i] = 0xFF;
276+
jsOverrideMask2[i] = 0x00;
277+
}
278+
}
150279
};
151280

152281
class EmuStateScriptObject: public QObject
@@ -574,11 +703,6 @@ private slots:
574703
void stopScript(void);
575704
};
576705

577-
// Formatted print
578-
//int LuaPrintfToWindowConsole( __FCEU_PRINTF_FORMAT const char *format, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 2 );
579-
580-
//void PrintToWindowConsole(intptr_t hDlgAsInt, const char *str);
581-
582-
//int LuaKillMessageBox(void);
706+
uint8_t FCEU_JSReadJoypad(int which, uint8_t phyState);
583707

584708
#endif // __FCEU_QSCRIPT_ENABLE__

src/input.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,10 @@ static uint8 ReadGPVS(int w)
234234
return ret;
235235
}
236236

237+
#ifdef __FCEU_QSCRIPT_ENABLE__
238+
extern uint8_t FCEU_JSReadJoypad(int which, uint8_t phyState);
239+
#endif
240+
237241
static void UpdateGP(int w, void *data, int arg)
238242
{
239243
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)
247251
joy[0] = *(uint32 *)joyports[0].ptr;;
248252
joy[2] = *(uint32 *)joyports[0].ptr >> 16;
249253
#endif
254+
255+
#ifdef __FCEU_QSCRIPT_ENABLE__
256+
joy[0]= FCEU_JSReadJoypad(0,joy[0]);
257+
joy[2]= FCEU_JSReadJoypad(2,joy[2]);
258+
#endif
250259
}
251260
else
252261
{
@@ -259,6 +268,11 @@ static void UpdateGP(int w, void *data, int arg)
259268
joy[1] = *(uint32 *)joyports[1].ptr >> 8;
260269
joy[3] = *(uint32 *)joyports[1].ptr >> 24;
261270
#endif
271+
272+
#ifdef __FCEU_QSCRIPT_ENABLE__
273+
joy[1]= FCEU_JSReadJoypad(1,joy[1]);
274+
joy[3]= FCEU_JSReadJoypad(3,joy[3]);
275+
#endif
262276
}
263277

264278
}

0 commit comments

Comments
 (0)