https://bugs.winehq.org/show_bug.cgi?id=47070
--- Comment #21 from Cameron Moore moore.cameron1111@gmail.com --- Ok, so I've got a workaround / hack to make it work now. Most definitely not appropriate to integrate into Wine, but here is a link to a Github release if anyone would like to try it out: https://github.com/cammoore1/proton-wine/releases/tag/Workaround. NOTE: the build should only be used for Dragon Age Inquisition as it will probably cause bugs in other programs.
I'm not completely sure on the specifics of why the bug happens, but there are two main threads involved. Thread A owns the window object for the game. Thread B makes all the calls to XInputGetState. However, Thread B checks if the window has focus to receive keyboard inputs every frame. Thread B calls AttachThreadInput to attach its message queue to the Thread A's window a few times before the bug starts occurring along with one separate time at the start where Thread A attaches Thread B's message queue to the window as well. The message queue is detached one last time and then Thread B no longer has access to the window.
My workaround checks GetFocus for when it starts receiving Null for a response (meaning it does not have access to a window anymore). Prior to this, AttachThreadInput stores the IDs of the two threads which call the function the very first time (hopefully this works with the EA App as I've been debugging this with Origin which doesn't seem to call either of the two WINAPI functions as long as you load straight into the game from the Origin library menu). When GetFocus realizes it does not have a window for the thread, it calls AttachThreadInput with the two thread IDs. This allows Thread B to access the window, which let's GetFocus return the proper window handle, which then let's the program access XInputGetState meaning the controller finally works.
Anyway, as far as the final cause of the bug: it might be because of thread prioritization causing Thread B to AttachThreadInput to be called by it last as the only time Thread A calls it, it does not detach the message queue afterwards. This leads me to believe that the bug might just be caused by incomplete wine functionality / stubs. Although, this part is speculation.