From f7c62fc9be338a23fe3bb1dc8e773e52958fca15 Mon Sep 17 00:00:00 2001 From: gfp34 Date: Sun, 16 Oct 2022 09:37:33 -0400 Subject: [PATCH] Implemented joypad_set --- python_scripts/joypad_test.py | 9 ++++- src/fceupython.h | 2 ++ src/input.cpp | 11 +++++++ src/python-engine.cpp | 62 ++++++++++++++++++++++++++++++++--- 4 files changed, 79 insertions(+), 5 deletions(-) diff --git a/python_scripts/joypad_test.py b/python_scripts/joypad_test.py index f9697f76..8420a403 100644 --- a/python_scripts/joypad_test.py +++ b/python_scripts/joypad_test.py @@ -2,5 +2,12 @@ import emu import joypad 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() \ No newline at end of file diff --git a/src/fceupython.h b/src/fceupython.h index 40674464..4ccc6aee 100644 --- a/src/fceupython.h +++ b/src/fceupython.h @@ -4,4 +4,6 @@ void FCEU_PythonFrameBoundary(); void FCEU_LoadPythonCode(const char* filename); +uint8 FCEU_PythonReadJoypad(int,uint8); + #endif //_FCEUPYTHON_H \ No newline at end of file diff --git a/src/input.cpp b/src/input.cpp index 592d5e50..72ea73ef 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -31,6 +31,7 @@ #ifdef _S9XLUA_H #include "fceulua.h" #endif +#include "fceupython.h" #include "input.h" #include "vsuni.h" #include "fds.h" @@ -245,6 +246,11 @@ static void UpdateGP(int w, void *data, int arg) joy[0] = *(uint32 *)joyports[0].ptr;; joy[2] = *(uint32 *)joyports[0].ptr >> 16; #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 { @@ -257,6 +263,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 + + 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]); } } diff --git a/src/python-engine.cpp b/src/python-engine.cpp index c4398604..76744973 100644 --- a/src/python-engine.cpp +++ b/src/python-engine.cpp @@ -7,10 +7,11 @@ #include namespace py = pybind11; -#include "fceupython.h" #include "movie.h" #include "state.h" +#include "types.h" +#include "fceupython.h" // Are we running any code right now? static char* pythonScriptName = NULL; @@ -31,6 +32,13 @@ static const char *button_mappings[] = { "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() { @@ -94,9 +102,35 @@ static py::dict joypad_getup(int player) 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(button_mappings[i])) { + auto buttonIn = input[button_mappings[i]]; + auto buttonInType = py::type::of(buttonIn); + + bool buttonBool = false; + bool buttonIsString = false; + + if (py::isinstance(buttonIn)) { + buttonBool = buttonIn.cast(); + } else if (py::isinstance(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) { @@ -112,6 +146,8 @@ PYBIND11_EMBEDDED_MODULE(joypad, m) m.def("readdown", joypad_getdown); m.def("getup", joypad_getup); m.def("readup", joypad_getup); + m.def("set", joypad_set); + m.def("write", joypad_set); } void FCEU_PythonFrameBoundary() @@ -168,7 +204,25 @@ void FCEU_LoadPythonCode(const char* filename) std::thread(pythonStart, std::string(filename)).detach(); 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.