protonscr

GetControllerState from FnTable always zeroes VRControllerState_t struct

steamvrclosed
ValveSoftware/SteamVR-for-Linux#35 · opened 2017-03-10 by valentindavid · updated 2018-08-08 · 7 comments · github
Vvalentindavid 2017-03-10 github

Your system information

  • Steam client version (build number or date): 1488992261
  • Distribution (e.g. Ubuntu): Gentoo
  • Graphics driver version (run nvidia-settings): 375.27.13
  • Gist for SteamVR System Information: https://gist.github.com/valentindavid/64b4ee1ebdca82af92cdf6d4f0bedb10
  • Opted into Steam client beta?: Yes
  • Opted into SteamVR beta?: Yes
  • Have you checked for system updates?: Yes

Please describe your issue in as much detail as possible:

GetControllerState from FnTable:IVRSystem_015 (C API) always return with a zeroed VRControllerState_t struct when GetControllerState from IVRSystem_015 returns with a correct VRControllerState_t struct.

This is a problem for ViveCraft for example that uses the C API through JOpenVR. No button on the controllers work.

Here is an example of program. When running, hold buttons. It should then show non zero values. But it is always 0.

#include <openvr.h>
#include <openvr_capi.h>
#include <iostream>
#include <chrono>
#include <thread>

int main() {
  vr::HmdError err;
  auto ignored = vr::VR_Init(&err, vr::VRApplication_Scene);

  auto vrsystem = (VR_IVRSystem_FnTable*)vr::VR_GetGenericInterface("FnTable:IVRSystem_015", &err);

  if (err) {
    std::cerr << vr::VR_GetVRInitErrorAsSymbol(err) << "\n";
    return 1;
  }
  while (true) {
    for (vr::TrackedDeviceIndex_t i = 0; i < vr::k_unMaxTrackedDeviceCount; ++i) {
      VRControllerState_t state;
      if (vrsystem->GetControllerState(i, &state, sizeof(state))) {
	std::cerr << state.ulButtonPressed << "\n";
      }
    }
    std::this_thread::sleep_for(std::chrono::seconds(1));
  }
  return 0;
}
Vvalentindavid 2017-03-10 github

Also note, you need to fix the openvr_capi.h to compile with GCC: __stdcall is not valid in GCC.

Vvalentindavid 2017-03-10 github

This is an alignment problem. sizeof(VRControllerState_t) is 64, when sizeof(vr::VRControllerState_t) is 60. There are 4 bytes missing between the two first fields.

Jjohnv-valve maintainer 2017-03-13 github

openvr_capi.h needs the same #pragma pack(push, 4) that openvr.h has.

Jjohnv-valve maintainer 2017-05-25 github

this is fixed in the current openvr SDK.

DDmytry 2017-07-31 github

It's not fixed. On Linux 64 bit, the size of C struct is 64 and the size of C++ struct is 60 , and looking at the sources, we have https://github.com/ValveSoftware/openvr/blob/master/headers/openvr_capi.h#L1336 no pack pragma around it (padding of 4 after unPacketNum because the subsequent value is 8 byte sized) and https://github.com/ValveSoftware/openvr/blob/master/headers/openvr.h#L890 has pack 4 pragma around it, but only for linux and mac.

CChristophHaag 2018-08-07 github

Can confirm, the C header is still missing pragma pack. I know GetControllerState() is deprecated, but still...

PPlagman 2018-08-08 github

I believe this is fixed and will be out in the next SDK.

Nothing extracted yet.