Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

joystick: Add nxdk joystick driver #5

Merged
merged 3 commits into from
Jul 5, 2019
Merged

Conversation

dracc
Copy link

@dracc dracc commented May 7, 2019

Still untested apart from build time smoke test.

Will require XboxDev/nxdk#106.

@dracc dracc marked this pull request as ready for review May 8, 2019 05:29
@dracc
Copy link
Author

dracc commented May 8, 2019

Apart from requiring the SDL_Hint SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_INPUTS, this is working beautifullly.

Edit: seems the hint is only necessary when running more than one thread.

@dracc dracc force-pushed the nxdk_joystick branch 2 times, most recently from 57a802f to 2913adf Compare May 9, 2019 11:33
case 3:
return "Pad 4";
return "Xbox Pad 4";
Copy link
Member

@JayFoxRox JayFoxRox May 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should handle it like XInput, https://github.com/XboxDev/nxdk-sdl/blob/nxdk/src/joystick/windows/SDL_xinputjoystick.c#L73

Note that XInput was developed on the original Xbox - so it's the API we try to replicate.

This is pretty much what we already do it, but we should probably follow its style more closely with Original Xbox %s #%u.


We'll probably also need another joystick driver in the future, for non-Xbox devices plugged via USB; which should probably use the USB device name: https://github.com/XboxDev/nxdk-sdl/blob/nxdk/src/joystick/windows/SDL_dinputjoystick.c#L501

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this again.. wouldn't SDL_snprintf(name, sizeof(name), "XInput Controller #%u", 1 + userid); be exactly what we want? We are essentially emulating xinput with xpad (and I intend to bring it even closer in the future).

I think SDL / Windows XInput refers to the 360 variant with LB/RB and digital buttons, but otherwise we are 1:1 XInput. It even has the Xbox-style input device stuff.

Eitherway, we can fix it later, because we probably won't have users in the first weeks (or they'll have to update their code).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably related to #5 (comment), will have to wait until xpad changes have been implemented.

@dracc dracc force-pushed the nxdk_joystick branch 4 times, most recently from c461868 to 0109e5f Compare May 10, 2019 08:43
@dracc dracc mentioned this pull request May 11, 2019
@dracc dracc force-pushed the nxdk_joystick branch 4 times, most recently from 83a1279 to a6c6ffb Compare June 12, 2019 06:37

static void SDL_XBOX_JoystickDetect() {
// Implemented in XInputGetEvents
return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why doesn't this call said function then?

What is that comment trying to express?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might need a comment that this is temporary:

If XInput is initialized without polling it should auto-detect gamepads.

It just doesn't do that right now, because of nxdk bugs (which makes USBGetEvents necessary).

Additionally, it should be checked that it's fine to auto-update the detected joysticks even if this wasn't called.
I consider this a minor issue, but it might need special attention in the future.
So if an app loops over joysticks twice, is it allowed for the return values to change, even if SDL wasn't explicitly asked to update the list?

static SDL_JoystickGUID SDL_XBOX_JoystickGetDeviceGUID(int index) {
/* FIXME: This should be implemented properly */
SDL_JoystickGUID ret;
SDL_memset(&ret.data, 0, sizeof(ret.data));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there other data in SDL_JoystickGUID that needs to be set to zero (now or in the future)? What do other backends do?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SDL_JoystickGUID is defined as typedef struct { Uint8 data[16]; } SDL_JoystickGUID;. I guess it could make sense to null the full struct for future proofing.

@JayFoxRox
Copy link
Member

Bikeshed complete. Handing over to someone else for final review.

I did test this a while ago with the sample PR in nxdk, but not after recent changes.

Important note: Only this PR is fine. The samples in nxdk still need work.

Copy link
Member

@Ernegien Ernegien left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly nits...

#include <assert.h>
#include <stdbool.h>

#define NUMAXES 6 /* LStickY, LStickX, LTrigg, RStickY, RStickX, RTrigg */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: underscore after NUM in these defines for readability unless these are SDL standards.

#define NUMAXES 6 /* LStickY, LStickX, LTrigg, RStickY, RStickX, RTrigg */
#define NUMBTNS 10 /* A, B, X, Y, black, white, back, start, LThumb, RThumb */
#define NUMHATS 1 /* D-pad */
#define NUMBLLS 0 /* No balls here */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: might as well fully expand BLLS into BALLS (unless these are SDL standards), what's an extra character when you're already using four for AXES?

#define NUMHATS 1 /* D-pad */
#define NUMBLLS 0 /* No balls here */

#define BUTTONDEADZONE 0x20
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: underscore separation for readability unless these are SDL standards.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine


#ifdef SDL_JOYSTICK_XBOX
if (!mapping) {
SDL_bool existing;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any need to assert what existing should be after the call or does it not matter?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, only know that the Linux code above doesn't do any extra checks.

}

static int SDL_XBOX_JoystickOpen(SDL_Joystick *joystick, int index) {
if (g_Pads[index].hPresent == 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably assert the index argument isn't out-of-bounds in the g_Pads array.

return 0;
}

static bool analogButtonPressed(SDL_Joystick *joystick, int button) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: possibly rename button to button_index here and elsewhere.

return;
}

static const char* SDL_XBOX_JoystickNameForDeviceIndex(int i) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: rename i to index as referred to in the rest of the code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be SDL standard stuff. Otherwise a good suggestion

}

static bool digitalButtonPressed(SDL_Joystick *joystick, int button) {
return (joystick->hwdata->padData->CurrentButtons.usDigitalButtons & button) != 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Parentheses can be removed here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GCC gives this; warning: & has lower precedence than !=; != will be evaluated first [-Wparentheses]

}

static void analogButtonUpdate(SDL_Joystick *joystick, int button, int index) {
if (analogButtonPressed(joystick, button) != joystick->buttons[index]) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably assert index is within bounds here and elsewhere.

axisUpdate(joystick, xpi->sLThumbX, 0);
axisUpdate(joystick, xpi->sLThumbY, 1);
ltrigg = xpi->CurrentButtons.ucAnalogButtons[XPAD_LEFT_TRIGGER];
ltrigg = ((ltrigg << 8) | ltrigg) - (1 << 15);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should convert this into a MACRO or utility function for reuse and readability.

Copy link
Member

@JayFoxRox JayFoxRox Jun 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only used twice. This is fine as-is (in my opinion).

Copy link
Member

@thrimbor thrimbor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested the current state of the branch in XQEMU and on my 1.0 Xbox. Everything seemed to work and nothing catches my eye code-wise, so apart from @Ernegien's remarks, I'd say this is fine to get merged.

@dracc dracc force-pushed the nxdk_joystick branch 6 times, most recently from 0761259 to cac21e0 Compare July 4, 2019 22:34
@thrimbor thrimbor merged commit 96d6213 into XboxDev:nxdk Jul 5, 2019
JayFoxRox pushed a commit to JayFoxRox/nxdk-sdl that referenced this pull request Jun 6, 2020
Make sure the thread is actually paused, and context backep-up, before
SurfaceView is destroyed (eg surfaceDestroyed() actually returns).

Add a timeout when surfaceDestroyed() is called, and check 'backup_done' variable.

It prevents crashes like:

  #00  pc 000000000000c0d0  /system/lib64/libutils.so (android::RefBase::incStrong(void const*) const+8)
  #1  pc 000000000000c7f4  /vendor/lib64/egl/eglSubDriverAndroid.so (EglAndroidWindowSurface::UpdateBufferList(ANativeWindowBuffer*)+284)
  #2  pc 000000000000c390  /vendor/lib64/egl/eglSubDriverAndroid.so (EglAndroidWindowSurface::DequeueBuffer()+240)
  #3  pc 000000000000bb10  /vendor/lib64/egl/eglSubDriverAndroid.so (EglAndroidWindowSurface::GetBuffer(EglSubResource*, EglMemoryDesc*)+64)
  #4  pc 000000000032732c  /vendor/lib64/egl/libGLESv2_adreno.so (EglWindowSurface::UpdateResource(EsxContext*)+116)
  XboxDev#5  pc 0000000000326dd0  /vendor/lib64/egl/libGLESv2_adreno.so (EglWindowSurface::GetResource(EsxContext*, EsxResource**, EsxResource**, int)+56)
  XboxDev#6  pc 00000000002ae484  /vendor/lib64/egl/libGLESv2_adreno.so (EsxContext::AcquireBackBuffer(int)+364)
  XboxDev#7  pc 0000000000249680  /vendor/lib64/egl/libGLESv2_adreno.so (EsxContext::Clear(unsigned int, unsigned int, unsigned int, EsxClearValues*)+1800)
  XboxDev#8  pc 00000000002cb52c  /vendor/lib64/egl/libGLESv2_adreno.so (EsxGlApiParamValidate::GlClear(EsxDispatch*, unsigned int)+132)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

5 participants