adamdruppe / arsd

This is a collection of modules that I've released over the years. Most of them stand alone, or have just one or two dependencies in here, so you don't have to download this whole repo.
http://arsd-official.dpldocs.info/arsd.html
530 stars 125 forks source link

joystick.d: Mapping issues on Linux, but only in release builds #326

Open BitterlyIronic opened 2 years ago

BitterlyIronic commented 2 years ago

I'm running into a strange issue with joystick.d. When compiling a debug build everything seems to work correctly, but on compiling a release build the joystick mappings seem to get all jumbled up. In the example below, in debug mode the program will loop until the cross button is pressed, as expected, but in release mode the cross button is inverted and the program will only loop while the button is held. Other buttons seem to get mixed up in different ways beyond just being inverted, too.

import std.stdio;
import arsd.joystick;

void main()
{
    auto hasController = enableJoystickInput(0, -1, -1, -1) > 0;

    if (hasController) {
        version (linux) readJoystickEvents(joystickFds[0]);
        auto upd = getJoystickUpdate(0);
        auto isPressed = upd.buttonWasJustPressed(Button.cross);

        while (!isPressed) {
            isPressed.writeln;
            version (linux) readJoystickEvents(joystickFds[0]);
            upd = getJoystickUpdate(0);
            isPressed = upd.buttonWasJustPressed(Button.cross);
        }
    }
}
adamdruppe commented 2 years ago

You running on linux? And release mode you mean dmd -release or something else?

BitterlyIronic commented 2 years ago

Yep, running on Linux and building with dub build -b=release

adamdruppe commented 2 years ago

ok, it is possible one of the asserts is more important than i thought or some optimization done in there actually broke things... ill have to look later

adamdruppe commented 2 years ago

OK, yeah, I can reproduce strange behavior with dub build release. dub release uses -release -inline -O to dmd.... three flags I recommend people never use.

Strangely any one of those flags seems to break it.

Adding -debug fixes it again. oh dear.

adamdruppe commented 2 years ago

This is weird.... it does seem to work better if you set

auto isPressed = false;//upd.buttonWasJustPressed(Button.cross);

to ensure it does at least two reads. But I still don't really know what is going on. The different build flags read the same data off the js file, yet react differently and I don't see why.

adamdruppe commented 2 years ago

riddle me this

                                joystickState[player].buttons[event.number] = event.value ? 255 : 0;
                                writeln(player, " ", event.number, " ", event.value, " ", joystickState[player].buttons[event.number]);

js_event(1612852304, 0, 129, 0) 0 0 0 255 js_event(1612852304, 0, 129, 1) 0 1 0 255 js_event(1612852304, 0, 129, 2) 0 2 0 255 js_event(1612852304, 0, 129, 3) 0 3 0 255

So the value is zero every time. That should set it to zero, right? Yet it says 255.

adamdruppe commented 2 years ago

And adding

writeln(player, " ", event.number, " ", event.value, " ", joystickState[player].buttons[event.number]);//, " != ", event.value ? 255 : 0);

uncommenting that print changes the value. I'm pretty sure this is a bug in dmd.

BitterlyIronic commented 2 years ago

I tried rolling back to an older version of joystick.d that had worked for me previously and I'm seeing the same behavior, so it's seeming more and more like a compiler issue to me too.

adamdruppe commented 2 years ago

yeah i haven't changed joystick.d much for a long time. I'd suggest just avoiding that -release thing. ldc's optimizations seem to work without breaking it, i think it is a dmd bug specifically. it is really messed up, i think it is incorrectly extending the byte or something like that. i guess i could disassemble it but ugh