Falcon BMS on GNU/Linux
-
OK… Think I’ve fixed it now. Seems like it was some settings within BMS that I hadn’t set correctly - maybe triple buffering switched on? Not sure. Need more testing, but at least I got it to get into the game with vanilla wine built by me - now to test your patch!
-
Cheers! Yes, triple buffering needs to be disabled.
Once you get it done get ftnoir-posix
-
Cheers! Yes, triple buffering needs to be disabled.
Once you get it done get ftnoir-posix
Don’t have the kit for that yet… Don’t even have a joystick!!! (any recommendations?)
But - with your patch I am now getting 35 fps in instant action!!! Woohoo!
-
Saitek X65F or Warthog.
Disable GLSL and HDR and anisotropy.
-
On the contrary, BMS is one of only 2 reasons I still have a Windows install in the house at all.
I agree, its the same at our house.
-
With Catalyst driver it’s possible to play with HDR. The only thing that needs to be off is triple buffering.
-
Have you tried out playing online under Wine?
-
Yes. It works.
-
Hi,
Sorry to bring this old thread back, but I’d like to say big thanks to all that made possible to run this new incarnation of Falcon 4 on Linux, be it the Wine team or the BMS team themselves. I’ve been playing around a bit with it and everything seems to work fine so, again, bg kudos to anyone involved.Just as a reference, in case it might help anyone, I’m using it on a Fedora 18 system, using Wine 1.5.24 and an nVidia card (using the propietary drivers). The program was installed through excellent PlayOnLinux tool, with no specific quirks. On F4-BMS side, I only had to disable “Triple Buffering” in Config tool, as otherwise I was getting a completely black screen (although the program was indeed responsible).
By the way, I’ve been working for some time in a new joystick programming tool for Linux, which includes complete support for modes & shift buttons, axis programming through bands, etc… In case anyone muight be interested in using it (I’m using it right now with my old Saitek X-45), the link is in my sig.
Kind regards,
Eduard Huguet -
@Eduard
Are you using TrackIR, or any other track? -
Nope, sorry. I don’t have TrackIR, only the X-45 HOTAS.
I do have a webcam, however. Is there any webcam-based head tracking solution on Linux that I could try?
Eduard -
Shameless plug:
https://github.com/opentrack/opentrack
Builds and runs fine under Linux with TrackIR emulation.
-
Looks promising. I’ll give it a try, thanks
Regards,
Eduard Huguet -
Quite frankly, I don’t like the kernel module approach you chose. It’d be better to do a userland driver, stability-wise. Especially if you parse XML and do other fancy stuff. Look at xboxdrv, there’s some overlap and it’s done pure-userland.
-
Quite frankly, I don’t like the kernel module approach you chose. It’d be better to do a userland driver, stability-wise. Especially if you parse XML and do other fancy stuff. Look at xboxdrv, there’s some overlap and it’s done pure-userland.
Hi,
Thank you very much for your feedback, I really appreciate it. As for the comments you do, first of all let me make clear that the XML parsing is not done at all at kernel level, that definitely would be a very bad idea. This part is handled by the helper C/C++ library, which is used by the userspace tools. The assignments are then loaded into the driver using a fairly simple IOCTL-based API, similar to that of standard joydev module. The kernel module does some “fancy” things, as you put it ;), but definitely nothing very complicated.As for the userland vs in-kernel model, let me explain why I choosed the second path: when I started the project, I tried first the userland way, by implementing a daemon that read events from the joystick (using joydev’s standard JS API), then inject mouse & keyboard events into graphical stack by using XTEST X server extension. Although this part mainly worked, it had a main drawback, which is the impossibility to deny the target game (or program) the access to the source joystick event that originating the event. I mean, not all games allow you to “deassign” a button or an axis so it does nothing on the game, so if you program a button to issue a keyboard shortcut when it’s pressed, you can’t stop the game from performing also the action it had assigned internally to that button, in addition to the programmed shortcut’s one. IMHO, this was a serious limitation.
Instead, by implementing a a kernel-level filter you do have a very early access to the events sent by the joystick driver, in fact right before joydev itself receives them, and you have the ability to filter them out and generate your own from an internal virtual input generator. That renders the kernel approach very powerful, as you can map a button event to a shortcut without userspace ever knowing about the original event.
Regarding xboxdrv (a project I wasn’t aware of, frankly, but I’ve been thoroughly reading the documentation so I could at least know how it is implemented) it uses a different approach, which is directly reading RAW device data sent through libusb, then mapping source events to generated events that get injected through uinput extension (a kernel extension that allows to inject events into kernel input subsystem from userspace). Although it seems a valid approach, IMVHO it might have some flaws:
- It needs to decode the RAW data sent by the device, which is something that should definitely be done by the low level hardware driver, not from userspace. The input subsystem in Linux kernel is very cleverly designed, so all input devices transform the data sent by the hardware into a “normalized” set of events, so userspace does not need to know about device specifics. By re-doing this from userspace, your are definitely going an step back.
- I can’t clearly see if you can “hide” original events sent from the joystick. I suspect you can’t, as it suggests you to remove the “/dev/js0” created by joydev module so your game use the one created by xboxdrv. Again, this doesn’t look very good…
- It’s limited to USB devices. OK, this might not be an issue, as most game devices available are USB, but still.
That said, there are things I like from it, like the fact they use “uinput” to inject the events from userspace. This is something definitively worth looking at it, as I could take part of the mapping code out from the kernel and move it to userspace, but I’m sure I’d still need to use kernel module in order to provide the low level filtering.
Anyway, the approach used by JSMapper renders it quite universal, as it operates on the “normalized” set of events injected into the input subystem, so it didn’t need to care about any device specifics, it should work out-of-the-box on all of them. Obviosly, there still a lot of work to do, specially on the userland side, like i.e. providing a graphical UI to load profiles into the driver, or even a graphical UI to create profiles so you don’t need to mess around with XML format.
Hope this helps, and don’t hesitate to contact me if you have any other question
Kind regards,
Eduard HuguetPS: and sorry for the lengthy post…
-
How’s your ioctl API? Do you bound-check userland-passed pointers correctly? Is there a need for locking, and if so, do you follow kernel API?
As for xboxdrv, you missed the evdev interface. It’s confusingly both an XBox gamepad driver and a mapper for evdev, well, events. Try the latter to see how to do it in userspace.
I assume you can hide access through exclusivity level in xboxdrv. It’s possible to deny usage of the original device. If the game has hardcoded js0 input (doubtful!), try playing with udev for specifying which device should be named js0.
It’s not limited to usb, everything with evdev-compatible works.
Another problem is kernel ABI breakage, unless you want your code merged, you’ll struggle a lot, experience crashes, etc, as whoever’s in charge of the kernel’s subsystem breaks the API/ABI. Only userland API is stable.
-
How’s your ioctl API? Do you bound-check userland-passed pointers correctly? Is there a need for locking, and if so, do you follow kernel API?
As for xboxdrv, you missed the evdev interface. It’s confusingly both an XBox gamepad driver and a mapper for evdev, well, events. Try the latter to see how to do it in userspace.
I assume you can hide access through exclusivity level in xboxdrv. It’s possible to deny usage of the original device. If the game has hardcoded js0 input (doubtful!), try playing with udev for specifying which device should be named js0.
It’s not limited to usb, everything with evdev-compatible works.
Another problem is kernel ABI breakage, unless you want your code merged, you’ll struggle a lot, experience crashes, etc, as whoever’s in charge of the kernel’s subsystem breaks the API/ABI. Only userland API is stable.
Hi,
Yes, I do check parameter boundaries, and yes, I do use spinlocks / mutexes wherever is necessary, of course. I used joydev implementation (which I assume rock-solid) as a base for my module. I’m not saying I’m absolutely sure there is no bugs, but obviously if there are they will be fixed. If you are interested, check jsmapper_api.h file in src/linux/drivers/input folder.With regards to API/ABI breakage…, well, shit happens. I’ve been developing software for more than 20 years now, in multiple platforms (including Windows, Linux and embedded devices), and I’ve had to deal with that multiple times. Sooner or later, a library or a framework or something you rely on decides to make a fundamental change, and you need to deal with it and adapt your code. Again, shit happens. As for Linux kernel, it’s a known fact that 3rd party drivers must deal with kernel modifications, and that kernel modules needs to be compiled against every specific kernel for it to load the module. Distros provide mechanisms to deal with that (akmod, etc…) so again, no big deal here.
Merge the code into the kernel will be fine, but I’m not sure this projects fits into the general kernel. A possibility would be to merge it with existing _joydev _module, thus adding device programming to standard Linux joystick API. Anyway, this is something to discuss
in the future, not now probably.As a side note, quite recently I had to deal with an API change in the kernel, specifically the way in which char devices are registered, which got change in 3.8 version. I did have to adapt the code so it would compile against new kernels, while maintaining compatibility with old code but, again, it was no big deal.
And regarding xboxdrv: yes, I did read about the evdev interface, which I guess helps providing compatibility over any input device connected, but this doesn’t solve the (to me) fundamental problem of how to avoid the target game receiving original events from the device. Yes, you can mess with udev and so, but that renders things a little complicated.
The advantage of JSMapper is that the regular ‘js0’ joystick device will still be there, and the game will use it in a transparent way (JSMapper creates a different device the controlling API). It just won’t get the events that get filtered by JSMapper, instead it will receive keyboard events just as if it had been entered on the real keyboard.
Kind regards,
Eduard Huguet__ -
The advantage of JSMapper is that the regular ‘js0’ joystick device will still be there, and the game will use it in a transparent way (JSMapper creates a different device the controlling API)
Is it that much better than returning EBUSY on open(2) js0, which xboxdrv does when using exclusive mode?
But perhaps this is different than my use-case (xboxdrv for mapping DX buttons > 31 and axes over 7 for Wine).
Good luck with your project, I was trying to save you the trouble of page faults in kernel mode But given you have twice the length of experience than I do, you most likely know what you’re doing.
I’m looking for testers of the Wine protocol for opentrack, a few revisions ago Project Evil (NPClient.dll and friends) was refactored and it’s hard to test in a VM without an actual game. Want to give it a try?
Can you map axes too? The Saitek x65 crapola comes with nine axes and one HID node…
-
The advantage of JSMapper is that the regular ‘js0’ joystick device will still be there, and the game will use it in a transparent way (JSMapper creates a different device the controlling API)
Is it that much better than returning EBUSY on open(2) js0, which xboxdrv does when using exclusive mode?
Mmmmh… That way you completely blocks game from accessing the device, and I didn’t want to do that. They way it’s done, with JSMapper the js0 is created normally and can get accessed by the app in order to access i.e. the axes, there’s no need to redirect it to a new, different js device. The app will detect the joystick in the usual way and use it, but it simply won’t get any event notifications for buttons that are mapped by JSMapper.
Good luck with your project, I was trying to save you the trouble of page faults in kernel mode But given you have twice the length of experience than I do, you most likely know what you’re doing.
I learned the hard way to issue a sync command before execution tests…
I’m looking for testers of the Wine protocol for opentrack, a few revisions ago Project Evil (NPClient.dll and friends) was refactored and it’s hard to test in a VM without an actual game. Want to give it a try?
Definitely yes! I simply need to find the time to install the required compile dependencies and play with it a bit. Is there any documentation out there about how to perform? Anyway, I have a very old & crappy webcam, so I don’t expect anything spectacular…
Can you map axes too? The Saitek x65 crapola comes with nine axes and one HID node…
If by mapping axes you mean assign actions to play when the axis is moved then yes, you can. It works by defining “bands” over the axis, which can get assigned to actions to be played. I got the idea from old Dhauzimmer’s drivers for Saitek X-45, a set of non-official drivers that definitely improved the software provided by Saitek in Windows.
Kind regards,
Eduard Huguet -
Nah, I mean creating axes in a new device, copied from the old one.
Required for head tracker itself:
opencv 2.4.3+, flandmark from git
Required for opentrack:
opencv 2.4.3+, libqxt, Qt 4.
CMake runs the setup process and will whine whenever something’s missing. I recommend using ‘cmake-gui’ in order to set up Wine support et al.
Better yet, skype me at sthalik or email [email protected] if you run into issues. I’m chatty enough