winrt.windows.gaming.input.RawGameController.get_current_reading
markdude247 opened this issue · 18 comments
Python 3.9
Method Expects 3 Arrays. First array consists of X(button_count) Bools, Second array consists of X(switch_count) GameControllerSwitchPosition, Third consists of X(axis_count) floats. When running RawGameController.get_current_reading(array1, array2, array3), The function is rejected and you receive errror: "RuntimeError: The parameter is incorrect.". This method works perfectly fine with C#
Can you share your full code? The bindings expect these parameters to be a Python list
object.
each parameter is a list
Tip: wrap the code like this so we can read it
```python
# code goes here
```
from winrt.windows.gaming import input as winInput
import time
class __dualshock4_remote__:
def __init__(self, winRT_RawController:winInput.RawGameController):
self.type = "dualshock4"
self.rawAPI = winRT_RawController
self.button_count = winRT_RawController.button_count
self.axis_count = winRT_RawController.axis_count
self.switch_count = winRT_RawController.switch_count
self.wireless = winRT_RawController.is_wireless
self.headset = winRT_RawController.headset
self.ID = winRT_RawController.non_roamable_id
self.button_states = []
for i in range(self.button_count):
self.button_states.append(False)
self.axis_states = []
for i in range(self.axis_count):
self.axis_states.append(0.0)
self.switch_states = []
for i in range(self.switch_count):
self.switch_states.append(winInput.GameControllerSwitchPosition)
print(self.button_states, self.switch_states, self.axis_states)
# [False, False, False, False,.... (14x)], [GameControllerSwitchPosition], [0, 0, 0, 0 ,0 ,0]
print(winRT_RawController.get_current_reading)
# Code will not function past this
self.refresh = winRT_RawController.get_current_reading(
self.button_states,
self.switch_states,
self.axis_states
)
def __repr__(self) -> str:
return "< Dual Shock Remote >"
class __controllers__(list):
def __init_subclass__(cls) -> None:
return super().__init_subclass__()
def get_dualshock(self) -> __dualshock4_remote__:
# Get the first Dualshock remote
for item in self:
if item.type == "dualshock4":
return item
def get_controllers(timeout=5):
troller = timeout
while troller > 0:
raw_controllers = []
gamePads = winInput.RawGameController.get_raw_game_controllers()
for i in range(gamePads.size):
controller = gamePads.get_at(i)
raw_controllers.append(controller)
time.sleep(0.25)
if len(raw_controllers) > 0:
break
troller -= 0.25
controllers = __controllers__()
# Create a list item
for controller in raw_controllers:
#Parse through the found controllers and match them to their class.
if controller.axis_count == 6 and controller.button_count == 14 and controller.hardware_vendor_id == 1356:
#These parameters match the dual shock remote.
controllers.append(__dualshock4_remote__(controller))
return controllers
ps4_remote = get_controllers().get_dualshock()
[GameControllerSwitchPosition]
GameControllerSwitchPosition
is a Python type, so this is a list of type
rather than a list of GameControllerSwitchPosition
. So maybe [GameControllerSwitchPosition.CENTER]
works?
I'll give it a go once the remote charges
No success, Still the same response. Invalid parameter. It there an option to know exactly which parameter?
The corresponding code that works in C# is as follows:
bool[] buttons = new bool[remote.ButtonCount];
GameControllerSwitchPosition[] switches = new GameControllerSwitchPosition[remote.SwitchCount];
double[] axis = new double[remote.AxisCount];
remote.GetCurrentReading(buttons, switches, axis);
Invalid parameter. It there an option to know exactly which parameter?
No.
The corresponding code that works in C# is as follows:
FWIW, the Python equivalent should be this. (your code does the same thing, this is just fewer lines)
self.button_states = [False] * self.button_count
self.axis_states = [0.0] * self.axis_count
self.switch_states = [winInput.GameControllerSwitchPosition.CENTER] * self.switch_count
self.refresh = winRT_RawController.get_current_reading(
self.button_states,
self.switch_states,
self.axis_states
)
Not sure what else to suggest other than looking at the generated PyWinRT code for the get_current_reading()
to see if it doesn't something unusual.
where can I find that file and it's contents?
you have to generate it yourself using this repository
No luck. Must be something with translation.
Here is the generated code:
static PyObject* RawGameController_GetCurrentReading(py::wrapper::Windows::Gaming::Input::RawGameController* self, PyObject* args) noexcept
{
Py_ssize_t arg_count = PyTuple_Size(args);
if (arg_count == 3)
{
try
{
auto param0_count = py::convert_to<winrt::com_array<bool>::size_type>(args, 0);
winrt::com_array<bool> param0 ( param0_count, py::empty_instance<bool>::get() );
auto param1_count = py::convert_to<winrt::com_array<winrt::Windows::Gaming::Input::GameControllerSwitchPosition>::size_type>(args, 1);
winrt::com_array<winrt::Windows::Gaming::Input::GameControllerSwitchPosition> param1 ( param1_count, py::empty_instance<winrt::Windows::Gaming::Input::GameControllerSwitchPosition>::get() );
auto param2_count = py::convert_to<winrt::com_array<double>::size_type>(args, 2);
winrt::com_array<double> param2 ( param2_count, py::empty_instance<double>::get() );
auto return_value = self->obj.GetCurrentReading(param0, param1, param2);
py::pyobj_handle out_return_value{ py::convert(return_value) };
if (!out_return_value)
{
return nullptr;
}
py::pyobj_handle out0{ py::convert(param0) };
if (!out0)
{
return nullptr;
}
py::pyobj_handle out1{ py::convert(param1) };
if (!out1)
{
return nullptr;
}
py::pyobj_handle out2{ py::convert(param2) };
if (!out2)
{
return nullptr;
}
return PyTuple_Pack(4, out_return_value.get(), out0.get(), out1.get(), out2.get());
}
catch (...)
{
py::to_PyErr();
return nullptr;
}
}
else
{
py::set_invalid_arg_count_error(arg_count);
return nullptr;
}
}
It looks like it takes sizes for arguments, so...
self.refresh, self.button_states, self.axis_states, self.switch_states = winRT_RawController.get_current_reading(
self.button_count,
self.switch_count,
self.axis_count
)
Here is the generated code
Thanks. I am very new to how source code works. It seems like this is it. It's odd how much it changed vs. C# and Microsoft API Docs. No errors and it is refreshing.
self.refresh, self.button_states, self.switch_states, self.axis_states,
This IS in fact what is being return. Thank you sir!
(12442722443, [False, False, False, False, False, False, False, False, False, False, False, False, False, False], [0], [0.5019607843137255, 0.5019607843137255, 0.5137254901960784,
0.0, 0.0, 0.5019607843137255])
(Timestamp, [Button States], [Switch (Directional Pad) State], [Axis States])
You were a great help. I really do appreciate it!