Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Linux support #90

Open
wants to merge 27 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5453ed7
Compiles on linux, UDP based IPC for driver, no linux hooking capabil…
AngriestSCV Aug 28, 2022
d23704e
Added CMake & openvr
AngriestSCV Aug 29, 2022
ab9f0e5
Cleaning up build
AngriestSCV Aug 29, 2022
8c11089
CMake improvements
AngriestSCV Aug 29, 2022
095b335
Updating manifest handling
AngriestSCV Aug 29, 2022
fddc727
Improved gitignore
AngriestSCV Aug 29, 2022
a6081d6
Swaping out verbose preprocessor platform checks
AngriestSCV Aug 29, 2022
01442d2
Build fixes
AngriestSCV Aug 30, 2022
7f2e041
Fixing new clone build issue
AngriestSCV Aug 30, 2022
bfa1c3e
Imporving initial build process on Linux
AngriestSCV Sep 2, 2022
e66339e
Fixing reversed mouse in Linux VR
AngriestSCV Sep 4, 2022
2360f80
Allow for better handling of dropped UDP packets
AngriestSCV Sep 5, 2022
5d34f84
Reducing windows delta
AngriestSCV Sep 5, 2022
5adc5f2
Moving linux config path to StaticConfig
AngriestSCV Sep 5, 2022
2debe7d
Windows compatibility fix
AngriestSCV Sep 5, 2022
d69aac3
better readme to include Linux build instructions
AngriestSCV Sep 5, 2022
de98a3a
Linux config file fixes
AngriestSCV Sep 5, 2022
87d174b
Fixing up some fresh build issues.
AngriestSCV Sep 5, 2022
723c10a
Fixing config finding bug
AngriestSCV Sep 27, 2022
d70cb84
First steps on resolving change requests
AngriestSCV Oct 17, 2022
e6c76e1
Builds again after stripping many preprocessor statements
AngriestSCV Oct 19, 2022
e5087a0
Linux changes!
AngriestSCV Oct 22, 2022
67ec6b5
Better .gitignore
AngriestSCV Oct 22, 2022
dda4445
Builds under linux again, now with much less preprocessor
AngriestSCV Oct 23, 2022
c1511a3
Add executable to memory permissions when writing hook
AngriestSCV Oct 23, 2022
e5b0bae
Reverting logging change
AngriestSCV Oct 23, 2022
a4151fc
Replacing spaces with tabs
AngriestSCV Oct 23, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,12 @@ ipch
/OpenVR-SpaceCalibratorDriver/x64/
/x64/
/lib/boost*
*.o
*.a
*.srctrlprj
*.srctrldb
*.srctrlbm
*.out
OpenVR-SpaceCalibratorDriver/01spacecalibrator/bin/linux64/
build
*.gitignore
9 changes: 9 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[submodule "OpenVR-SpaceCalibrator/gl3w"]
path = OpenVR-SpaceCalibrator/gl3w
url = https://github.com/skaslev/gl3w.git
[submodule "modules/imgui"]
path = modules/imgui
url = https://github.com/ocornut/imgui.git
[submodule "modules/openvr"]
path = modules/openvr
url = https://github.com/ValveSoftware/openvr.git
120 changes: 120 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
cmake_minimum_required(VERSION 3.10)

project (OpenVR-SpaceCalibrator VERSION 1.0)
add_definitions(-D__linux__)

set(CMAKE_BUILD_TYPE Debug)
set(DRIVER_LOG_FILE "/tmp/spaceCalDriverLog.txt" CACHE PATH "Driver Log Path" )
set(LINUX_CONFIG_DIR ".config/OpenVR-SpaceCalibrator" CACHE PATH "Config subdirectory (from HOME)" )

add_library(imgui
lib/imgui/imgui.cpp
lib/imgui/imgui_demo.cpp
lib/imgui/imgui_draw.cpp
lib/imgui/imgui_impl_glfw.cpp
lib/imgui/imgui_impl_opengl3.cpp
modules/imgui/backends/imgui_impl_glfw.cpp
)

find_library(glfw libglfw.so)
find_library(GL libGL.so)
find_library( openvr_api libopenvr_api.so PATHS ./modules/openvr/bin/linux64/libopenvr_api.so )

include_directories(OpenVR-SpaceCalibratorDriver)
include_directories(/usr/include/eigen3)
include_directories(lib/gl3w/include)
include_directories(lib)
include_directories(modules/openvr/headers)

add_library( gl3w lib/gl3w/src/gl3w.c )

#configure_file(LinixConfig.h.in LinuxConfig.h)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)

add_executable(OpenVR-SpaceCalibrator
OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp
OpenVR-SpaceCalibrator/Calibration.cpp
OpenVR-SpaceCalibrator/Configuration.cpp
OpenVR-SpaceCalibrator/EmbeddedFiles.cpp
OpenVR-SpaceCalibrator/IPCClient.cpp
OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp
OpenVR-SpaceCalibrator/UserInterface.cpp
OpenVR-SpaceCalibrator/stdafx.cpp
./OpenVR-SpaceCalibratorDriver/compat.cpp
./OpenVR-SpaceCalibratorDriver/Logging.cpp
)
TARGET_LINK_LIBRARIES(OpenVR-SpaceCalibrator PRIVATE openvr_api imgui gl3w GL glfw)

add_library(
driver_01spacecalibrator
SHARED
OpenVR-SpaceCalibratorDriver/OpenVR-SpaceCalibratorDriver.cpp
OpenVR-SpaceCalibratorDriver/Hooking.cpp
OpenVR-SpaceCalibratorDriver/IPCServer.cpp
OpenVR-SpaceCalibratorDriver/InterfaceHookInjector.cpp
OpenVR-SpaceCalibratorDriver/Logging.cpp
OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.cpp
OpenVR-SpaceCalibratorDriver/compat.cpp
OpenVR-SpaceCalibratorDriver/dllmain.cpp
)

set_target_properties(driver_01spacecalibrator PROPERTIES
OUTPUT_NAME driver_01spacecalibrator
PREFIX ""
)

#######################################################################################
set( APP_MANIFEST_PATH ${CMAKE_INSTALL_PREFIX}/share/openvr-spacecalibrator/manifest.vrmanifest )
set( DRIVER_INSTALLER_PATH ${CMAKE_INSTALL_PREFIX}/share/openvr-spacecalibrator )
set( DRIVER_MANIFEST_PATH ${CMAKE_INSTALL_PREFIX}/lib/steamvr/OpenVR-SpaceCalibrator/01spacecalibrator )
configure_file( StaticConfig.h.in StaticConfig.h )

include_directories("${CMAKE_CURRENT_BINARY_DIR}")

configure_file( ./OpenVR-SpaceCalibrator/manifest.vrmanifest ${CMAKE_CURRENT_BINARY_DIR}/manifest.vrmanifest )
configure_file( ./OpenVR-SpaceCalibratorDriver/01spacecalibrator/driver.vrdrivermanifest ${CMAKE_CURRENT_BINARY_DIR}/driver.vrdrivermanifest )
configure_file( ./driverInstall.py ${CMAKE_CURRENT_BINARY_DIR}/driverInstall.py )


#######################################################################################
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/manifest.vrmanifest
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/openvr-spacecalibrator
)

install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/driver.vrdrivermanifest
DESTINATION lib/steamvr/OpenVR-SpaceCalibrator/01spacecalibrator
)

install(
TARGETS OpenVR-SpaceCalibrator
)
install(
TARGETS driver_01spacecalibrator
DESTINATION lib/steamvr/OpenVR-SpaceCalibrator/01spacecalibrator/bin/linux64/
)

install(
FILES driverInstall.py
DESTINATION "${DRIVER_INSTALLER_PATH}"
)

find_package(Git QUIET)

if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
# Update submodules as needed
option(GIT_SUBMODULE "Check submodules during build" ON)
if(GIT_SUBMODULE)
message(STATUS "Submodule update")
execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE GIT_SUBMOD_RESULT)
if(NOT GIT_SUBMOD_RESULT EQUAL "0")
message(FATAL_ERROR "git submodule update --init --recursive failed with ${GIT_SUBMOD_RESULT}, please checkout submodules")
endif()
endif()
endif()

4 changes: 2 additions & 2 deletions OpenVR-SpaceCalibrator/Calibration.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ struct CalibrationContext
Progress
} type = String;

Message(Type type) : type(type) { }
Message(Type _type) : type(_type) { }

std::string str;
int progress, target;
Expand Down Expand Up @@ -120,4 +120,4 @@ void InitCalibrator();
void CalibrationTick(double time);
void StartCalibration();
void LoadChaperoneBounds();
void ApplyChaperoneBounds();
void ApplyChaperoneBounds();
121 changes: 117 additions & 4 deletions OpenVR-SpaceCalibrator/Configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,21 @@
#include <picojson.h>

#include <string>
#include <iostream>
#include "stdio.h"
#include <fstream>
#include <iomanip>
#include <limits>

#include "Logging.h"

#ifdef __linux__
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include "StaticConfig.h"
#define LINUX_CONFIG_FILE "spacecal-config.json"
#endif

static picojson::array FloatArray(const float *buf, int numFloats)
{
picojson::array arr;
Expand All @@ -25,7 +35,7 @@ static void LoadFloatArray(const picojson::value &obj, float *buf, int numFloats
throw std::runtime_error("expected array, got " + obj.to_str());

auto &arr = obj.get<picojson::array>();
if (arr.size() != numFloats)
if (arr.size() != (size_t) numFloats)
throw std::runtime_error("wrong buffer size");

for (int i = 0; i < numFloats; i++)
Expand Down Expand Up @@ -142,17 +152,77 @@ static void WriteProfile(CalibrationContext &ctx, std::ostream &out)
out << profilesV.serialize(true);
}

#ifdef __linux__
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be a bit worried that the use of #ifdef scattered about the codebase will create maintenance problems in the future. Usually the way this is approached in larger codebases would be to refactor out the code that needs to differ into its own function, then have a set of windows-specific or linux-specific .cpp files. Having it scattered everywhere makes it hard to see what differs between the platforms, and because the surface area that differs is so ad-hoc, it makes it too easy to forget to carry across a change between the two variants.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can swap things over to that. I can see how it would be a better solution.

// NOP
#else
static const char *RegistryKey = "Software\\OpenVR-SpaceCalibrator";
static void LogRegistryResult(LSTATUS result)
{
char *message;
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, 0, result, LANG_USER_DEFAULT, (LPSTR)&message, 0, NULL);
std::cerr << "Opening registry key: " << message << std::endl;
}

static const char *RegistryKey = "Software\\OpenVR-SpaceCalibrator";
#endif

static std::string ReadRegistryKey()
{
#ifdef __linux__

char configPath[1024];
const char * home = getenv("HOME");
snprintf( configPath, 1024, "%s/" LINUX_CONFIG_DIR, home);

struct stat statResult;
if(stat(LINUX_CONFIG_DIR, &statResult)){
if(errno != 2){ // no idea why 2 is returned instead of the documented ENOTDIR
int rr = errno;
LOG("Error determining if %s is a directory: %s, %s", configPath, strerror(rr), strerror(2));
return "";
} else {
int rr = errno;
LOG("The directory %s is confirmed to not exist %d-%s", configPath, rr, strerror(rr));
int retCode;

char cmd[1500];
snprintf(cmd, 1500, "mkdir -p %s", configPath);
LOG("Running: %s", cmd);
if( (retCode = system(cmd)) ){
LOG("Error %d making directory " LINUX_CONFIG_DIR, retCode);
return "";
}
}
}

char configFilePath[2000];
snprintf(configFilePath, 2000, "%s/" LINUX_CONFIG_FILE, configPath);

LOG("Opening file at %s", configFilePath);

FILE* file = fopen(configFilePath, "r");







if(!file) return "";

std::string ret;
const int buffSize = 4097;
int count = 0;
char buff[buffSize];
buff[buffSize-1] = 0;

do{
count = fread((void*) buff, 1, buffSize, file);
if(count > 0){
ret += buff;
}
}while(buffSize == count);
fclose(file);
return ret;
#else
DWORD size = 0;
auto result = RegGetValueA(HKEY_CURRENT_USER_LOCAL_SETTINGS, RegistryKey, "Config", RRF_RT_REG_SZ, 0, 0, &size);
if (result != ERROR_SUCCESS)
Expand All @@ -173,10 +243,52 @@ static std::string ReadRegistryKey()

str.resize(size - 1);
return str;
#endif
}

static void WriteRegistryKey(std::string str)
{
#ifdef __linux__
struct stat statResult;

char configPath[1024];
const char * home = getenv("HOME");
snprintf( configPath, 1024, "%s/" LINUX_CONFIG_DIR, home);

if(stat(LINUX_CONFIG_DIR, &statResult)){
if(errno != 2){ // no idea why 2 is returned instead of the documented ENOTDIR
int rr = errno;
LOG("Error determining if %s is a directory: %s, %s", configPath, strerror(rr), strerror(2));
return;
} else {
int rr = errno;
LOG("The directory %s is confirmed to not exist %d-%s", configPath, rr, strerror(rr));
int retCode;

char cmd[1500];
snprintf(cmd, 1500, "mkdir -p %s", configPath);
LOG("Running: %s", cmd);
if( (retCode = system(cmd)) ){
LOG("Error %d making directory " LINUX_CONFIG_DIR, retCode);
return;
}
}
}

char configFilePath[2000];
snprintf(configFilePath, 2000, "%s/" LINUX_CONFIG_FILE, configPath);

FILE* file = fopen(configFilePath, "w");
if(!file) {
LOG("%s - %d-%s", "Error opening config file for writing", errno, strerror(errno));
return;
} else {
LOG("Opened file at %s to save settings", configFilePath);
}

fprintf(file, "%s", str.c_str());
fclose(file);
#else
HKEY hkey;
auto result = RegCreateKeyExA(HKEY_CURRENT_USER_LOCAL_SETTINGS, RegistryKey, 0, REG_NONE, 0, KEY_ALL_ACCESS, 0, &hkey, 0);
if (result != ERROR_SUCCESS)
Expand All @@ -192,6 +304,7 @@ static void WriteRegistryKey(std::string str)
LogRegistryResult(result);

RegCloseKey(hkey);
#endif
}

void LoadProfile(CalibrationContext &ctx)
Expand Down
4 changes: 4 additions & 0 deletions OpenVR-SpaceCalibrator/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,9 @@

#include "Calibration.h"

#ifdef __linux__
#include "StaticConfig.h"
#endif

void LoadProfile(CalibrationContext &ctx);
void SaveProfile(CalibrationContext &ctx);
Loading