FreePIE vJoy Input to Vive Output

Official forum for open source FreePIE discussion and development.
Post Reply
WolframRavenwolf
One Eyed Hopeful
Posts: 2
Joined: Mon Mar 06, 2017 3:43 pm

FreePIE vJoy Input to Vive Output

Post by WolframRavenwolf »

I spent several hours in vain trying to figure out how I can map vJoy inputs to Vive motion controller outputs. Hopefully someone on this forum can help me find a solution.

My goal is to use the VirZOOM exercise bike which works as a game controller (outputting as vJoy or Xbox controller) to control the Vive motion controllers so I can pedal through Google Earth VR. :)

Using zelmon64's xbox_vive_emulation script, I can control the Vive wands in-game with an Xbox controller emulating Razer Hydra. This allows me to move through Google Earth VR using the Xbox controller (holding RBumper + RTrigger + RStick to touch the touchpad in the top spot, moving forward).

Now I "only" need to send these inputs from my bike, using vJoy. But I only found code samples for using vJoy as output, not input, and when I use vJoy[0] in my script (e. g. "diagnostics.watch(vJoy[0].y)") I get the error "vJoy Device 1 is already owned by another feeder" (although I don't want to feed to vJoy, I just want to read it as input).

I'd be very grateful for any advice on how to proceed. Thanks in advance for your kind assistance.
MarijnS95
One Eyed Hopeful
Posts: 34
Joined: Tue Dec 22, 2015 12:52 pm

Re: FreePIE vJoy Input to Vive Output

Post by MarijnS95 »

As you noticed, vJoy is only able to output/emulate a regular DirectInput controller, so you won't be using it in this project.

In fact, if the VirZOOM acts like an xbox 360 controller (I was not able to verify this), you should be able to use that example script. You might have to change the axis/button mapping, but that shouldn't be too hard if you follow the names in the code and use the autocomplete popup.

If by
outputting as vJoy
you mean it's a DirectInput controller (joystick), you'll have to replace all the

Code: Select all

xbox360[i]
to

Code: Select all

joystick[i]
, as well as use the correct axis notation. Buttons can be retrieved with .getDown(idx) or .getPressed(idx).

If that doesn't help, I'd like to know how the device shows up in the "game controller" settings. You can find this in the start menu and/or the configuration panel.
WolframRavenwolf
One Eyed Hopeful
Posts: 2
Joined: Mon Mar 06, 2017 3:43 pm

Re: FreePIE vJoy Input to Vive Output

Post by WolframRavenwolf »

Thank you very much for the quick response. Your comment helped me a lot.

Instead of trying to work with vJoy, I simply had to read from joystick to get the input from the VirZOOM Gamepad Emulator (which uses vJoy itself to emulate a gamepad). This works and should allow me to continue working on the script.

By the way, the Xbox controller emulation of VirZOOM Gamepad Emulator didn't work. It requires placing several xinput DLLs in the target's folder and although I chose the FreePIE folder for that, Xbox inputs didn't get registered at all (but no problem since vJoy works).

Is there any proper documentation for how FreePIE works? I found the scripting wiki page and some examples, but no overview of variables (like joystick) or functions (like .getDown(idx) or .getPressed(idx)), so further reference would be very helpful.
MarijnS95
One Eyed Hopeful
Posts: 34
Joined: Tue Dec 22, 2015 12:52 pm

Re: FreePIE vJoy Input to Vive Output

Post by MarijnS95 »

Looks like VirZOOM uses these two third party tools (vJoy and x360ce) instead of building an actual driver for their device. Which isn't that easy and requires signing, so this seems like a good alternative.
Instead of trying to work with vJoy[...]
Again, you won't be working with vJoy, because it's a DirectInput (joystick) emulator. It allows games that support DirectInput to read from the virtual joystick, and in this case it allows FreePIE to read from it through the same mechanism. Which (as you know already) is joystick on the python side.

I don't know why the xbox controller doesn't work, when you place the files there they should be loaded instead of the original xinput dll... (But for me SlimDX (the library FreePIE uses to read from DirectInput and XInput devices) is in both the installation folder, as well as the plugins folder. So you could try placing the xinput files there as well, just for giggles).

As far as I know there's no real documentation for every function/property. It should be pretty straightforward though if you look at the autocomplete. Just type joystick followed by a period, and you'll see all the available axes. .getDown(idx) simply returns whether the button with index idx is currently pressed (this is similar to what you'd see in the "USB game controllers" menu.

All that said though, the best way to read from the VirZOOM is to sit somewhere inbetween their gamepad emulation tool. That is, have their code handle the interaction with the VirZOOM, so we can get the data from it, without having to go through vJoy and DirectInput again.
For the fun of it (and I need something to be distracted from studying :P), I wrote a plugin for FreePIE to do this: https://github.com/MarijnS95/FreePIE/tree/virzoom. It's based on their UnrealEngine plugin. Sadly, because their interface is only 64 bit, I had to recompile FreePIE in 64-bit. This will break other FreePIE plugins, but this is just to see if this is a viable solution. Then, some trickery can be done with a shim process and some IPC.
I assume that you do not have Visual Studio and are not willing to dive into all the code, so I compiled everything and uploaded it here.

You can use the following example script. If you need more, check the autocomplete!

Code: Select all

import time

if starting:
	connected = VirZOOM.connect()
	if connected:
		diagnostics.debug("Connected to VirZOOM!")
	else:
		diagnostics.debug("Not connected to VirZOOM :(")
	lastTime = time.clock()

if not connected:
	now = time.clock()
	VirZOOM.update(now - lastTime)
	lastTime = now
	
	diagnostics.watch(VirZOOM.speed)
	diagnostics.watch(VirZOOM.batteryVolts)
	diagnostics.watch(VirZOOM.dpadUp)
	diagnostics.watch(VirZOOM.dpadDown)
When running the script, first check the "console" tab to make sure it's connected, then move over to the watch tab to see the variables.
buz11
One Eyed Hopeful
Posts: 5
Joined: Sun Mar 12, 2017 1:03 pm

Re: FreePIE vJoy Input to Vive Output

Post by buz11 »

Eric the CTO from VirZOOM here. We'd love to see it control Google Earth VR as well, hadn't noticed that xbox-to-vive controller script before! If it helps I can supply C++ header/DLL to get our bike speed (and other sensors) directly, in 32-bit if you like.
MarijnS95
One Eyed Hopeful
Posts: 34
Joined: Tue Dec 22, 2015 12:52 pm

Re: FreePIE vJoy Input to Vive Output

Post by MarijnS95 »

Hi Eric, welcome to the FreePIE forums! Great to see someone from VirZOOM chiming in so quickly on a random forum :)

Having the 32bit library would be awesome, that way this can be added to FreePIE with much more ease (no shim process or 64-bit FreePIE which breaks all other kinds of plugins).

Also, having native VirZOOM support in FreePIE is a real plus for your product IMHO, as FreePIE has endless possibilities WRT button/axis mapping, combining inputs and outputting in just about any controller you can think of. Sadly I won't be able to test it as I don't own a VirZOOM nor a VR headset, and for the same reasons I'll probably not maintain it for long. But I'll make sure the 32bit library is added (including all the features I haven't implemented yet, for which the header is really useful btw), and that It's confirmed working :D
buz11
One Eyed Hopeful
Posts: 5
Joined: Sun Mar 12, 2017 1:03 pm

Re: FreePIE vJoy Input to Vive Output

Post by buz11 »

Sure, and thanks for supporting us and customers trying to use VirZOOM in new ways! Here's a 32-bit lib and header, we'd be happy to test after you integrate.

https://drive.google.com/open?id=0B5eeL ... 0VkR25maDA

And let us know if you could use a bike, the SDK itself doesn't require VR. ;-> Also thanks Wolfram, we're following and happy to support you!
MarijnS95
One Eyed Hopeful
Posts: 34
Joined: Tue Dec 22, 2015 12:52 pm

Re: FreePIE vJoy Input to Vive Output

Post by MarijnS95 »

Thanks! This DLL works fine with the regular 32bit FreePIE. I cleaned up the code a little and removed the .connect() and .update(), since FreePIE has builtin methods for that.

According to the header file state.Type > 0 indicates whether a bike is connected to the dongle. Have I understood correctly that state.Connected only indicates whether the dongle is plugged in (not whether a bike is connected to the dongle)?

On the same note, I'm guessing it's best to use one of the two variables to determine whether VZUpdateBike or VZConnectBike needs to be called, so that it can be unplugged and plugged back in while the script is running, right? Something along the lines of:

Code: Select all

if(connected) // Where connected is either state.Connected or state.Type > 0, depending on your answer to my first question
    VZUpdateBike(ref state, deltaTime);
else
    VZConnectBike(ref state);
And for a call to VZCloseBike, is it desired to use one of the two variables to determine whether it should be called?

Also, what's the scale of deltaTime? Seconds? Milliseconds?
buz11
One Eyed Hopeful
Posts: 5
Joined: Sun Mar 12, 2017 1:03 pm

Re: FreePIE vJoy Input to Vive Output

Post by buz11 »

Actually, state.Type > 0 just indicates whether our dongle is plugged into the PC. state.Connected then indicates whether a bike is powered on and connected to the dongle. You should ignore state.Connected before Type > 0, and state.<data> before Connected == true.

Some pseudo-code for correct initting and querying:

Code: Select all

 VZBikeState state;

   void Init()
   {
      VZInit(<path to dll directory>);
      VZConnectBike(&state));
   }

   void Update()
   {
      if (state.Type <= 0) 
      {
         VZConnectBike(&state); // wait for dongle to be plugged in
      }
      else
      {
         VZUpdateBike(&state, timeInSeconds()); // wall clock in seconds

         if (state.Connected) // bike is connected to dongle
         {
             // use state
         }
      }
   }

   void Quit()
   {
      VZCloseBike(); // fine to call in any state
   }
Last edited by buz11 on Thu Mar 16, 2017 4:35 am, edited 1 time in total.
buz11
One Eyed Hopeful
Posts: 5
Joined: Sun Mar 12, 2017 1:03 pm

Re: FreePIE vJoy Input to Vive Output

Post by buz11 »

I see to avoid confusion I could have named it VZOpenBike instead of VZConnectBike! In my defense this wasn't public code until a day ago. ;->
MarijnS95
One Eyed Hopeful
Posts: 34
Joined: Tue Dec 22, 2015 12:52 pm

Re: FreePIE vJoy Input to Vive Output

Post by MarijnS95 »

Indeed, the header file says type of bike dongle. However, the value specification mentions a value of 0 means "wired". Is that not valid?
(-1:no bike, 0:wired, 1:alpha, 2:beta)
I also notice just now that this info is written in comments above the function declarations as well... How could I've missed that D:

Anyway, I wired them both into a .connected property, so python scripts only need to check that in order to know whether the data is valid and usable. but just to be sure, diagnostics have been added in this example script:

Code: Select all

diagnostics.watch(VirZOOM.type)
if VirZOOM.type > 0:
	diagnostics.watch(VirZOOM.connected)
	if VirZOOM.connected:
		diagnostics.watch(VirZOOM.speed)
		diagnostics.watch(VirZOOM.batteryVolts)
The final product is on my github, and a compiled debug plugin is attached to this post. Just copy VirZOOMPlugin.dll to the plugins folder, and dump all the dlls in the lib folder directly into the FreePIE installation directory.
You do not have the required permissions to view the files attached to this post.
buz11
One Eyed Hopeful
Posts: 5
Joined: Sun Mar 12, 2017 1:03 pm

Re: FreePIE vJoy Input to Vive Output

Post by buz11 »

Awesome we'll give it a shot, hopefully Wolfram too!

You don't have to worry about handling Type==0 because "wired" was a very early prototype that no longer has support.

Thanks again
Post Reply

Return to “FreePIE”