Implemented joypad_set

This commit is contained in:
gfp34 2022-10-16 09:37:33 -04:00
parent 54d2a16330
commit f7c62fc9be
4 changed files with 79 additions and 5 deletions

View File

@ -2,5 +2,12 @@ import emu
import joypad import joypad
while True: while True:
print(f"PY: {joypad.read(1)}") # print(f"PY: {joypad.read(1)}")
fc = emu.framecount()
if (0 <= fc % 60 <= 10):
print("PY: A press")
joy_dict = {"A": True}
joypad.write(1, joy_dict)
emu.frameadvance() emu.frameadvance()

View File

@ -4,4 +4,6 @@
void FCEU_PythonFrameBoundary(); void FCEU_PythonFrameBoundary();
void FCEU_LoadPythonCode(const char* filename); void FCEU_LoadPythonCode(const char* filename);
uint8 FCEU_PythonReadJoypad(int,uint8);
#endif //_FCEUPYTHON_H #endif //_FCEUPYTHON_H

View File

@ -31,6 +31,7 @@
#ifdef _S9XLUA_H #ifdef _S9XLUA_H
#include "fceulua.h" #include "fceulua.h"
#endif #endif
#include "fceupython.h"
#include "input.h" #include "input.h"
#include "vsuni.h" #include "vsuni.h"
#include "fds.h" #include "fds.h"
@ -245,6 +246,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
joy[0]= *(uint32 *)joyports[0].ptr;
joy[0]= FCEU_PythonReadJoypad(0,joy[0]);
joy[2]= *(uint32 *)joyports[0].ptr >> 16;
joy[2]= FCEU_PythonReadJoypad(2,joy[2]);
} }
else else
{ {
@ -257,6 +263,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
joy[1]= *(uint32 *)joyports[1].ptr >> 8;
joy[1]= FCEU_PythonReadJoypad(1,joy[1]);
joy[3]= *(uint32 *)joyports[1].ptr >> 24;
joy[3]= FCEU_PythonReadJoypad(3,joy[3]);
} }
} }

View File

@ -7,10 +7,11 @@
#include <pybind11/embed.h> #include <pybind11/embed.h>
namespace py = pybind11; namespace py = pybind11;
#include "fceupython.h"
#include "movie.h" #include "movie.h"
#include "state.h" #include "state.h"
#include "types.h"
#include "fceupython.h"
// Are we running any code right now? // Are we running any code right now?
static char* pythonScriptName = NULL; static char* pythonScriptName = NULL;
@ -31,6 +32,13 @@ static const char *button_mappings[] = {
"A", "B", "select", "start", "up", "down", "left", "right" "A", "B", "select", "start", "up", "down", "left", "right"
}; };
// Our joypads.
static uint8 pythonjoypads1[4]= { 0xFF, 0xFF, 0xFF, 0xFF }; //x1
static uint8 pythonjoypads2[4]= { 0x00, 0x00, 0x00, 0x00 }; //0x
/* Crazy logic stuff.
11 - true 01 - pass-through (default)
00 - false 10 - invert */
static void emu_frameadvance() static void emu_frameadvance()
{ {
@ -94,9 +102,35 @@ static py::dict joypad_getup(int player)
return joy_get_internal(player, true, false); return joy_get_internal(player, true, false);
} }
// static void joypad_set(int player, py::dict input) { static void joypad_set(int player, py::dict input)
{
// Set up for taking control of the indicated controller
pythonjoypads1[player-1] = 0xFF; // .1 Reset right bit
pythonjoypads2[player-1] = 0x00; // 0. Reset left bit
// } for (int i=0; i < 8; i++) {
if (input.contains<std::string>(button_mappings[i])) {
auto buttonIn = input[button_mappings[i]];
auto buttonInType = py::type::of(buttonIn);
bool buttonBool = false;
bool buttonIsString = false;
if (py::isinstance<py::bool_>(buttonIn)) {
buttonBool = buttonIn.cast<bool>();
} else if (py::isinstance<py::str>(buttonIn)) {
buttonIsString = true;
} else {
continue;
}
if (buttonBool)
pythonjoypads2[player-1] |= 1 << i;
if (!buttonBool || buttonIsString)
pythonjoypads1[player-1] &= ~(1 << i);
}
}
}
PYBIND11_EMBEDDED_MODULE(emu, m) PYBIND11_EMBEDDED_MODULE(emu, m)
{ {
@ -112,6 +146,8 @@ PYBIND11_EMBEDDED_MODULE(joypad, m)
m.def("readdown", joypad_getdown); m.def("readdown", joypad_getdown);
m.def("getup", joypad_getup); m.def("getup", joypad_getup);
m.def("readup", joypad_getup); m.def("readup", joypad_getup);
m.def("set", joypad_set);
m.def("write", joypad_set);
} }
void FCEU_PythonFrameBoundary() void FCEU_PythonFrameBoundary()
@ -168,7 +204,25 @@ void FCEU_LoadPythonCode(const char* filename)
std::thread(pythonStart, std::string(filename)).detach(); std::thread(pythonStart, std::string(filename)).detach();
FCEU_PythonFrameBoundary(); FCEU_PythonFrameBoundary();
} }
/**
* Reads the buttons Python is feeding for the given joypad, in the same
* format as the OS-specific code.
*
* It may force set or force clear the buttons. It may also simply
* pass the input along or invert it. The act of calling this
* function will reset everything back to pass-through, though.
* Generally means don't call it more than once per frame!
*/
uint8 FCEU_PythonReadJoypad(int player, uint8 joyl)
{
joyl = (joyl & pythonjoypads1[player]) | (~joyl & pythonjoypads2[player]);
pythonjoypads1[player] = 0xFF;
pythonjoypads2[player] = 0x00;
return joyl;
}
/** /**
* Terminates a running Python scripts by killing the whole Python Interpretor. * Terminates a running Python scripts by killing the whole Python Interpretor.