From 5453ed7bd6ee922c1112639e3b4904310c3a8d91 Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Sun, 28 Aug 2022 18:28:36 -0500 Subject: [PATCH 01/27] Compiles on linux, UDP based IPC for driver, no linux hooking capabilities linux builder Now runs on linux warning crushing warning crushing Add subhook submodule Adding some override markers Misc small changes Improved comms driver now starts under linux still not hooking functions, but can call virutal functions with direct function pointers Kind of works now with hooking Linux port now functional Reducing delta to windows version adding linux to version string --- .gitignore | 7 + .gitmodules | 9 ++ OpenVR-SpaceCalibrator/Calibration.h | 4 +- OpenVR-SpaceCalibrator/Configuration.cpp | 40 ++++- OpenVR-SpaceCalibrator/Configuration.h | 2 + OpenVR-SpaceCalibrator/IPCClient.cpp | 22 ++- OpenVR-SpaceCalibrator/IPCClient.h | 14 +- .../OpenVR-SpaceCalibrator.cpp | 91 +++++++++-- OpenVR-SpaceCalibrator/UserInterface.cpp | 16 +- OpenVR-SpaceCalibrator/makefile | 78 ++++++++++ OpenVR-SpaceCalibrator/stdafx.h | 9 +- OpenVR-SpaceCalibrator/targetver.h | 5 +- OpenVR-SpaceCalibratorDriver/Comms.h | 141 ++++++++++++++++++ OpenVR-SpaceCalibratorDriver/Hooking.h | 52 ++++++- OpenVR-SpaceCalibratorDriver/IPCServer.cpp | 39 ++++- OpenVR-SpaceCalibratorDriver/IPCServer.h | 19 ++- .../InterfaceHookInjector.cpp | 12 +- OpenVR-SpaceCalibratorDriver/Logging.cpp | 17 ++- OpenVR-SpaceCalibratorDriver/Logging.h | 2 +- .../OpenVR-SpaceCalibratorDriver.h | 13 ++ .../ServerTrackedDeviceProvider.cpp | 26 +++- .../ServerTrackedDeviceProvider.h | 12 +- OpenVR-SpaceCalibratorDriver/build.sh | 24 +++ OpenVR-SpaceCalibratorDriver/compat.cpp | 43 ++++++ OpenVR-SpaceCalibratorDriver/compat.h | 44 ++++++ OpenVR-SpaceCalibratorDriver/dllmain.cpp | 19 +++ Protocol.h | 34 +++-- Version.h | 6 +- modules/gl3w | 1 + modules/imgui | 1 + 30 files changed, 726 insertions(+), 76 deletions(-) create mode 100644 .gitmodules create mode 100644 OpenVR-SpaceCalibrator/makefile create mode 100644 OpenVR-SpaceCalibratorDriver/Comms.h create mode 100755 OpenVR-SpaceCalibratorDriver/build.sh create mode 100644 OpenVR-SpaceCalibratorDriver/compat.cpp create mode 100644 OpenVR-SpaceCalibratorDriver/compat.h create mode 160000 modules/gl3w create mode 160000 modules/imgui diff --git a/.gitignore b/.gitignore index ecab4c34..577fa362 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,10 @@ ipch /OpenVR-SpaceCalibratorDriver/x64/ /x64/ /lib/boost* +*.o +*.a +*.srctrlprj +*.srctrldb +*.srctrlbm +*.out +OpenVR-SpaceCalibratorDriver/01spacecalibrator/bin/linux64/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..c052ab37 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,9 @@ +[submodule "OpenVR-SpaceCalibrator/gl3w"] + path = OpenVR-SpaceCalibrator/gl3w + url = https://github.com/skaslev/gl3w.git +[submodule "modules/gl3w"] + path = modules/gl3w + url = https://github.com/skaslev/gl3w.git +[submodule "modules/imgui"] + path = modules/imgui + url = https://github.com/ocornut/imgui.git diff --git a/OpenVR-SpaceCalibrator/Calibration.h b/OpenVR-SpaceCalibrator/Calibration.h index df55484c..46739c63 100644 --- a/OpenVR-SpaceCalibrator/Calibration.h +++ b/OpenVR-SpaceCalibrator/Calibration.h @@ -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; @@ -120,4 +120,4 @@ void InitCalibrator(); void CalibrationTick(double time); void StartCalibration(); void LoadChaperoneBounds(); -void ApplyChaperoneBounds(); \ No newline at end of file +void ApplyChaperoneBounds(); diff --git a/OpenVR-SpaceCalibrator/Configuration.cpp b/OpenVR-SpaceCalibrator/Configuration.cpp index 5dfc4911..fa1109af 100644 --- a/OpenVR-SpaceCalibrator/Configuration.cpp +++ b/OpenVR-SpaceCalibrator/Configuration.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include "stdio.h" #include #include #include @@ -25,7 +25,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(); - if (arr.size() != numFloats) + if (arr.size() != (size_t) numFloats) throw std::runtime_error("wrong buffer size"); for (int i = 0; i < numFloats; i++) @@ -142,17 +142,39 @@ static void WriteProfile(CalibrationContext &ctx, std::ostream &out) out << profilesV.serialize(true); } +#if !defined(_WIN32) && !defined(_WIN64) +// 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() { +#if !defined(_WIN32) && !defined(_WIN64) + FILE* file = fopen(LINUX_CONFIG_FILE, "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) @@ -173,10 +195,19 @@ static std::string ReadRegistryKey() str.resize(size - 1); return str; +#endif } static void WriteRegistryKey(std::string str) { +#if !defined(_WIN32) && !defined(_WIN64) + FILE* file = fopen(LINUX_CONFIG_FILE, "w"); + if(!file) std::cerr << "Error opening config file for writing"; + + 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) @@ -192,6 +223,7 @@ static void WriteRegistryKey(std::string str) LogRegistryResult(result); RegCloseKey(hkey); +#endif } void LoadProfile(CalibrationContext &ctx) diff --git a/OpenVR-SpaceCalibrator/Configuration.h b/OpenVR-SpaceCalibrator/Configuration.h index 43623a46..cee7d17f 100644 --- a/OpenVR-SpaceCalibrator/Configuration.h +++ b/OpenVR-SpaceCalibrator/Configuration.h @@ -2,5 +2,7 @@ #include "Calibration.h" +#define LINUX_CONFIG_FILE "/tmp/spacecal-config" + void LoadProfile(CalibrationContext &ctx); void SaveProfile(CalibrationContext &ctx); diff --git a/OpenVR-SpaceCalibrator/IPCClient.cpp b/OpenVR-SpaceCalibrator/IPCClient.cpp index eacafcd4..7e51236f 100644 --- a/OpenVR-SpaceCalibrator/IPCClient.cpp +++ b/OpenVR-SpaceCalibrator/IPCClient.cpp @@ -1,8 +1,12 @@ #include "stdafx.h" #include "IPCClient.h" +#include "Comms.h" #include +#if !defined(_WIN32) && !defined(_WIN64) +// NOP +#else static std::string LastErrorString(DWORD lastError) { LPSTR buffer = nullptr; @@ -15,15 +19,22 @@ static std::string LastErrorString(DWORD lastError) LocalFree(buffer); return message; } +#endif IPCClient::~IPCClient() { +#if !defined(_WIN32) && !defined(_WIN64) + //NOP +#else if (pipe && pipe != INVALID_HANDLE_VALUE) CloseHandle(pipe); +#endif } void IPCClient::Connect() { +#if !defined(_WIN32) && !defined(_WIN64) +#else LPTSTR pipeName = TEXT(OPENVR_SPACECALIBRATOR_PIPE_NAME); WaitNamedPipe(pipeName, 1000); @@ -39,7 +50,7 @@ void IPCClient::Connect() { throw std::runtime_error("Couldn't set pipe mode. Error: " + LastErrorString(GetLastError())); } - +#endif auto response = SendBlocking(protocol::Request(protocol::RequestHandshake)); if (response.type != protocol::ResponseHandshake || response.protocol.version != protocol::Version) { @@ -61,17 +72,25 @@ protocol::Response IPCClient::SendBlocking(const protocol::Request &request) void IPCClient::Send(const protocol::Request &request) { +#if !defined(_WIN32) && !defined(_WIN64) + pipe.Send(request); +#else DWORD bytesWritten; BOOL success = WriteFile(pipe, &request, sizeof request, &bytesWritten, 0); if (!success) { throw std::runtime_error("Error writing IPC request. Error: " + LastErrorString(GetLastError())); } +#endif } protocol::Response IPCClient::Receive() { protocol::Response response(protocol::ResponseInvalid); +#if !defined(_WIN32) && !defined(_WIN64) + pipe.Recv(&response); + return response; +#else DWORD bytesRead; BOOL success = ReadFile(pipe, &response, sizeof response, &bytesRead, 0); @@ -90,4 +109,5 @@ protocol::Response IPCClient::Receive() } return response; +#endif } diff --git a/OpenVR-SpaceCalibrator/IPCClient.h b/OpenVR-SpaceCalibrator/IPCClient.h index e8e7ee86..c525b9df 100644 --- a/OpenVR-SpaceCalibrator/IPCClient.h +++ b/OpenVR-SpaceCalibrator/IPCClient.h @@ -1,5 +1,11 @@ #pragma once +#if !defined(_WIN32) && !defined(_WIN64) +#include "compat.h" +#include "Comms.h" +#else +#endif + #include "../Protocol.h" class IPCClient @@ -14,5 +20,9 @@ class IPCClient protocol::Response Receive(); private: - HANDLE pipe = INVALID_HANDLE_VALUE; -}; \ No newline at end of file +#if !defined(_WIN32) && !defined(_WIN64) + Client pipe; +#else + HANDLE pipe = INVALID_HANDLE_VALUE; +#endif +}; diff --git a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp index 7aece1d1..923474ae 100644 --- a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp +++ b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp @@ -4,23 +4,43 @@ #include "EmbeddedFiles.h" #include "UserInterface.h" +#include +#include +#include +#include + +#if !defined(_WIN32) && !defined(_WIN64) +#include +#else +#include +#endif + #include #include #include -#include + + #include #include -#include +#if !defined(_WIN32) && !defined(_WIN64) +//NOP +#else #pragma comment(linker,"\"/manifestdependency:type='win32' \ name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +#endif #define OPENVR_APPLICATION_KEY "pushrax.SpaceCalibrator" +#if !defined(_WIN32) && !defined(_WIN64) +#else extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001; +#endif +//#define DEBUG_LOGS +#ifdef DEBUG_LOGS void CreateConsole() { static bool created = false; @@ -34,20 +54,22 @@ void CreateConsole() created = true; } } - -//#define DEBUG_LOGS +#endif void GLFWErrorCallback(int error, const char* description) { fprintf(stderr, "GLFW Error %d: %s\n", error, description); } -void openGLDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) +void openGLDebugCallback(GLenum /* source */, GLenum /* type */, GLuint id, GLenum /* severity */, GLsizei length, const GLchar *message, const void * /* userParam */ ) { fprintf(stderr, "OpenGL Debug %u: %.*s\n", id, length, message); } - +#if !defined(_WIN32) && !defined(_WIN64) +static void HandleCommandLine(wchar_t const * lpCmdLine); +#else static void HandleCommandLine(LPWSTR lpCmdLine); +#endif static GLFWwindow *glfwWindow = nullptr; static vr::VROverlayHandle_t overlayMainHandle = 0, overlayThumbnailHandle = 0; @@ -339,9 +361,41 @@ void RunLoop() } } +using convert_t = std::codecvt_utf8; +std::wstring_convert strconverter; + +std::string to_string(std::wstring wstr) +{ + return strconverter.to_bytes(wstr); +} + +std::wstring to_wstring(std::string str) +{ + return strconverter.from_bytes(str); +} + +#if !defined(_WIN32) && !defined(_WIN64) +int main(int argc, char ** argv) +#else int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) +#endif { + +#if !defined(_WIN32) && !defined(_WIN64) + wchar_t const * lpCmdLine; + std::wstring wide; + for(int i=1; i #include #include -#include +#include "../lib/imgui/imgui.h" struct VRDevice { @@ -67,14 +67,14 @@ void BuildMenu(bool runningInOverlay) { auto &io = ImGui::GetIO(); ImGuiStyle &style = ImGui::GetStyle(); - ImGui::Text(""); + ImGui::Text("%s", ""); if (CalCtx.state == CalibrationState::None) { if (CalCtx.validProfile && !CalCtx.enabled) { ImGui::TextColored(ImColor(0.8f, 0.2f, 0.2f), "Reference (%s) HMD not detected, profile disabled", CalCtx.referenceTrackingSystem.c_str()); - ImGui::Text(""); + ImGui::Text("%s", ""); } float width = ImGui::GetWindowContentRegionWidth(), scale = 1.0f; @@ -114,7 +114,7 @@ void BuildMenu(bool runningInOverlay) scale = 0.5; } - ImGui::Text(""); + ImGui::Text("%s", ""); if (ImGui::Button("Copy Chaperone Bounds to profile", ImVec2(width * scale, ImGui::GetTextLineHeight() * 2))) { LoadChaperoneBounds(); @@ -135,7 +135,7 @@ void BuildMenu(bool runningInOverlay) } } - ImGui::Text(""); + ImGui::Text("%s", ""); auto speed = CalCtx.calibrationSpeed; ImGui::Columns(4, NULL, false); @@ -194,7 +194,7 @@ void BuildMenu(bool runningInOverlay) break; case CalibrationContext::Message::Progress: float fraction = (float)message.progress / (float)message.target; - ImGui::Text(""); + ImGui::Text("%s", ""); ImGui::ProgressBar(fraction, ImVec2(-1.0f, 0.0f), ""); ImGui::SetCursorPosY(ImGui::GetCursorPosY() - ImGui::GetFontSize() - style.FramePadding.y * 2); ImGui::Text(" %d%%", (int)(fraction * 100)); @@ -205,7 +205,7 @@ void BuildMenu(bool runningInOverlay) if (CalCtx.state == CalibrationState::None) { - ImGui::Text(""); + ImGui::Text("%s", ""); if (ImGui::Button("Close", ImVec2(ImGui::GetWindowContentRegionWidth(), ImGui::GetTextLineHeight() * 2))) ImGui::CloseCurrentPopup(); } @@ -279,7 +279,7 @@ void BuildSystemSelection(const VRState &state) ImGui::SameLine(); ImGui::Combo("##TargetTrackingSystem", ¤tTargetSystem, &targetSystems[0], (int) targetSystems.size()); - if (currentTargetSystem != -1 && currentTargetSystem < targetSystems.size()) + if (currentTargetSystem != -1 && currentTargetSystem < (int) targetSystems.size()) { CalCtx.targetTrackingSystem = std::string(targetSystems[currentTargetSystem]); } diff --git a/OpenVR-SpaceCalibrator/makefile b/OpenVR-SpaceCalibrator/makefile new file mode 100644 index 00000000..6c91937f --- /dev/null +++ b/OpenVR-SpaceCalibrator/makefile @@ -0,0 +1,78 @@ +OFLAGS = +CC=g++ +STD=-std=c++14 +SHARED_FLAGS= -g -W -Wall -Wextra $(STD) -Wno-missing-field-initializers -Wshadow \ +-I ../OpenVR-SpaceCalibratorDriver/ \ +-isystem /usr/include/eigen3/ \ +-isystem /home/zack/src/openvr/headers \ +-isystem ../gl3w/build/include \ +-isystem ../modules/gl3w/build/include \ +-isystem ../lib/ \ +$(OFLAGS) + +CFLAGS=-c $(SHARED_FLAGS) + +LFLAGS= -g $(STD) $(OFLAGS) \ + -L /home/zack/src/openvr/lib/linux64 \ + -lGL -limgui -lopenvr_api -lglfw + +.PHONY:clean + +Objects=Calibration.o Configuration.o EmbeddedFiles.o IPCClient.o OpenVR-SpaceCalibrator.o UserInterface.o stdafx.o +Copy=gl3w.o imgui_impl_glfw.o imgui.a Logging.o compat.o + +all : $(Objects) spaceCal + +spaceCal : $(Objects) $(Copy) + $(CC) $(Std) $(Objects) $(Copy) $(LFLAGS) -o spaceCal + +$(Objects): %.o: %.cpp + $(CC) $(CFLAGS) $< + +gl3w.o: ../modules/gl3w/build/src/gl3w.c + $(CC) $(CFLAGS) ../modules/gl3w/build/src/gl3w.c -o gl3w.o + +imgui_impl_glfw.o: ../modules/imgui/backends/imgui_impl_glfw.cpp + $(CC) $(CFLAGS) ../modules/imgui/backends/imgui_impl_glfw.cpp -o imgui_impl_glfw.o + +imgui.a: ../lib/imgui/*cpp + rm -f imgui.a + $(CC) $(CFLAGS) ../lib/imgui/imgui.cpp + $(CC) $(CFLAGS) ../lib/imgui/imgui_demo.cpp + $(CC) $(CFLAGS) ../lib/imgui/imgui_draw.cpp + $(CC) $(CFLAGS) ../lib/imgui/imgui_impl_glfw.cpp + $(CC) $(CFLAGS) ../lib/imgui/imgui_impl_opengl3.cpp + ar rcs imgui.a imgui.o imgui_demo.o imgui_draw.o imgui_impl_glfw.o imgui_impl_opengl3.o + +Logging.o: ../OpenVR-SpaceCalibratorDriver/Logging.cpp + $(CC) $(CFLAGS) ../OpenVR-SpaceCalibratorDriver/Logging.cpp -o Logging.o + +compat.o: ../OpenVR-SpaceCalibratorDriver/compat.cpp + $(CC) $(CFLAGS) ../OpenVR-SpaceCalibratorDriver/compat.cpp -o compat.o + +dbg: spaceCal + gdb spaceCal + +run: spaceCal + ./spaceCal + +time: spaceCal + time ./spaceCal + +cache: spaceCal + rm c*grind* -f + valgrind --tool=cachegrind ./spaceCal + +call: spaceCal + rm c*grind* -f + valgrind --tool=callgrind --collect-jumps=yes --dump-instr=yes ./spaceCal + +inspect: + kcachegrind c*grind\.out\.* + +clean: + rm -f *o + rm -f imgui.a + rm -f spaceCal + rm -f c*grind\.out\.* + diff --git a/OpenVR-SpaceCalibrator/stdafx.h b/OpenVR-SpaceCalibrator/stdafx.h index b600ea54..76ab7157 100644 --- a/OpenVR-SpaceCalibrator/stdafx.h +++ b/OpenVR-SpaceCalibrator/stdafx.h @@ -1,12 +1,17 @@ #pragma once -#include "targetver.h" +#if !defined(_WIN32) && !defined(_WIN64) +#include +#include "compat.h" +#else +#include "targetver.h" #define WIN32_LEAN_AND_MEAN #include +#include +#endif #include #include #include -#include #include diff --git a/OpenVR-SpaceCalibrator/targetver.h b/OpenVR-SpaceCalibrator/targetver.h index 87c0086d..774e8e24 100644 --- a/OpenVR-SpaceCalibrator/targetver.h +++ b/OpenVR-SpaceCalibrator/targetver.h @@ -4,5 +4,8 @@ // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - +#if !defined(_WIN32) && !defined(_WIN64) +// NOP: not in linux build +#else #include +#endif diff --git a/OpenVR-SpaceCalibratorDriver/Comms.h b/OpenVR-SpaceCalibratorDriver/Comms.h new file mode 100644 index 00000000..9b59ff0b --- /dev/null +++ b/OpenVR-SpaceCalibratorDriver/Comms.h @@ -0,0 +1,141 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "Logging.h" +#include "../Protocol.h" + +class UDPServerSocket{ + int sock; + public: + UDPServerSocket(const UDPServerSocket& other) = delete; + UDPServerSocket& operator=(const UDPServerSocket& other) = delete; + + UDPServerSocket(){} + + + bool Open(unsigned short port){ + sockaddr_in my_addr = {}; + + my_addr.sin_family = AF_INET; + my_addr.sin_port = htons(port); + my_addr.sin_addr.s_addr = htonl(INADDR_ANY); + + //TODO verify that 0 is valid for UDP. + sock = socket(AF_INET, SOCK_DGRAM, 0); + if(sock == -1){ + LOG("%s", "Failed to create socket"); + return false; + } + + int err = bind(sock, (sockaddr*)&my_addr, sizeof(my_addr)); + if(err){ + LOG("%s", "Failed to bind socket"); + return false; + } + return true; + } + + template + bool Recv(RecvObj* obj, sockaddr* client, socklen_t* clientSize) { + size_t targetSize = sizeof(*obj); + size_t bytes = recvfrom(sock, (void*)obj, targetSize, 0, + client, clientSize); + if(bytes != targetSize){ + LOG("Error, recieved %d bytes when %d were expected", bytes, (int)targetSize); + return false; + } + else { + return true; + } + } + + template + bool Send(const SendObj& obj, sockaddr* sendTo, size_t sendToSize) { + ssize_t targetSize = sizeof(obj); + ssize_t bytes = sendto(sock, (void*)&obj, targetSize, 0, sendTo, sendToSize); + return targetSize == bytes; + } +}; + +template +class Comms{ + sockaddr_in lastClient; + socklen_t peer_addr_len; + + UDPServerSocket sock; + public: + Comms(const Comms& other) = delete; + Comms& operator=(const Comms& other) = delete; + + Comms(){ + if( !sock.Open(COMM_PORT_SERVER) ){ + LOG("%s", "Error opening server socket"); + } + } + + void Recv(RecvObj* obj){ + while(true){ + if(sock.Recv(obj, (sockaddr*) &lastClient, &peer_addr_len)){ + return; + } else { + LOG("%s", "failed to recve value"); + } + } + } + + void Send(const SendObj& obj ) { + sock.Send(obj, (sockaddr*) &lastClient, sizeof(lastClient)); + } +}; + + +template +class Client{ + sockaddr_in serverAddr = {}; + socklen_t peer_addr_len = {}; + + UDPServerSocket sock; + public: + Client(const Client& other) = delete; + Client& operator=(const Client& other) = delete; + + Client(){ + if( !sock.Open(COMM_PORT_CLIENT) ){ + LOG("%s", "Error opening server socket"); + } + + serverAddr.sin_family = AF_INET; + serverAddr.sin_port = htons(COMM_PORT_SERVER); + serverAddr.sin_addr.s_addr = INADDR_ANY; + } + + void Recv(RecvObj* obj){ + while(true){ + sockaddr_in lastClient; + lastClient.sin_family = AF_INET; + lastClient.sin_port = htons(COMM_PORT_SERVER); + lastClient.sin_addr.s_addr = INADDR_ANY; + + if(sock.Recv(obj, (sockaddr*) &lastClient, &peer_addr_len)){ + return; + } else { + LOG("%s", "failed to recve value"); + } + } + } + + void Send(const SendObj& obj ) { + sock.Send(obj, (sockaddr*) &serverAddr, sizeof(serverAddr)); + } +}; + diff --git a/OpenVR-SpaceCalibratorDriver/Hooking.h b/OpenVR-SpaceCalibratorDriver/Hooking.h index 9b1f71ed..3003aeb9 100644 --- a/OpenVR-SpaceCalibratorDriver/Hooking.h +++ b/OpenVR-SpaceCalibratorDriver/Hooking.h @@ -1,7 +1,16 @@ #pragma once #include "Logging.h" + +#if !defined(_WIN32) && !defined(_WIN64) +#include +#include "string.h" +#include +#else #include +#endif + + #include #include @@ -30,9 +39,41 @@ template class Hook : public IHook FuncType originalFunc = nullptr; Hook(const std::string &name) : IHook(name) { } - bool CreateHookInObjectVTable(void *object, int vtableOffset, void *detourFunction) +#if !defined(_WIN32) && !defined(_WIN64) + template + bool CreateHookInObjectVTable(void *object, int vtableOffset, T* detourFunction) + { + // For virtual objects, VC++ (and from what I can tell gcc) adds a pointer to the vtable as the first member. + // To access the vtable, we simply dereference the object. + void **vtable = *((void ***)object); + + // The vtable itself is an array of pointers to member functions, + // in the order they were declared in. + originalFunc = (FuncType) vtable[vtableOffset]; + targetFunc = (void*) vtable[vtableOffset]; + + uintptr_t otherPage = (uintptr_t) vtable & ~(uintptr_t) 4095; + int err = mprotect((void*) otherPage, 8196, PROT_READ | PROT_WRITE); + if(err){ + LOG("Failed to set memory protection %d-%s", err, strerror(errno)); + } + else { + //LOG("%s", "Setting vtable value"); + vtable[vtableOffset] = (void*) detourFunction; + //LOG("%s", "Resetting permissions vtable value"); + mprotect((void*) otherPage, 8196, PROT_READ | PROT_EXEC); + } + + + LOG("Enabled Linux hook for %s", name.c_str()); + enabled = true; + return true; + } +#else + template + bool CreateHookInObjectVTable(void *object, int vtableOffset, T* detourFunction) { - // For virtual objects, VC++ adds a pointer to the vtable as the first member. + // For virtual objects, VC++ (and from what I can tell gcc) adds a pointer to the vtable as the first member. // To access the vtable, we simply dereference the object. void **vtable = *((void ***)object); @@ -59,17 +100,22 @@ template class Hook : public IHook enabled = true; return true; } +#endif void Destroy() { +#if !defined(_WIN32) && !defined(_WIN64) + // should probably do something, but meh. +#else if (enabled) { MH_RemoveHook(targetFunc); enabled = false; } +#endif } private: bool enabled = false; void* targetFunc = nullptr; -}; \ No newline at end of file +}; diff --git a/OpenVR-SpaceCalibratorDriver/IPCServer.cpp b/OpenVR-SpaceCalibratorDriver/IPCServer.cpp index 5bbd0c0f..4a98dc74 100644 --- a/OpenVR-SpaceCalibratorDriver/IPCServer.cpp +++ b/OpenVR-SpaceCalibratorDriver/IPCServer.cpp @@ -2,6 +2,13 @@ #include "Logging.h" #include "ServerTrackedDeviceProvider.h" +#if !defined(_WIN32) && !defined(_WIN64) +#include "Comms.h" +#else + +#endif + + void IPCServer::HandleRequest(const protocol::Request &request, protocol::Response &response) { switch (request.type) @@ -34,17 +41,23 @@ void IPCServer::Run() void IPCServer::Stop() { - TRACE("IPCServer::Stop()"); + TRACE("%s", "IPCServer::Stop()"); if (!running) return; - stop = true; + +#if !defined(_WIN32) && !defined(_WIN64) + //NOP +#else SetEvent(connectEvent); mainThread.join(); running = false; TRACE("IPCServer::Stop() finished"); +#endif } - +#if !defined(_WIN32) && !defined(_WIN64) + //NOP +#else IPCServer::PipeInstance *IPCServer::CreatePipeInstance(HANDLE pipe) { auto pipeInst = new PipeInstance; @@ -61,9 +74,23 @@ void IPCServer::ClosePipeInstance(PipeInstance *pipeInst) pipes.erase(pipeInst); delete pipeInst; } +#endif void IPCServer::RunThread(IPCServer *_this) { +#if !defined(_WIN32) && !defined(_WIN64) + Comms comms; + + protocol::Response response; + protocol::Request request; + + while(!_this->stop){ + comms.Recv(&request); + _this->HandleRequest(request, response); + comms.Send(response); + } + LOG("%s", "Stop requested"); +#else _this->running = true; LPTSTR pipeName = TEXT(OPENVR_SPACECALIBRATOR_PIPE_NAME); @@ -125,10 +152,15 @@ void IPCServer::RunThread(IPCServer *_this) _this->ClosePipeInstance(pipeInst); } _this->pipes.clear(); +#endif } +#if !defined(_WIN32) && !defined(_WIN64) +//NOP +#else BOOL IPCServer::CreateAndConnectInstance(LPOVERLAPPED overlap, HANDLE &pipe) { + pipe = CreateNamedPipe( TEXT(OPENVR_SPACECALIBRATOR_PIPE_NAME), PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, @@ -218,3 +250,4 @@ void IPCServer::CompletedWriteCallback(DWORD err, DWORD bytesWritten, LPOVERLAPP pipeInst->server->ClosePipeInstance(pipeInst); } } +#endif diff --git a/OpenVR-SpaceCalibratorDriver/IPCServer.h b/OpenVR-SpaceCalibratorDriver/IPCServer.h index 8777704e..9d771c38 100644 --- a/OpenVR-SpaceCalibratorDriver/IPCServer.h +++ b/OpenVR-SpaceCalibratorDriver/IPCServer.h @@ -1,13 +1,18 @@ #pragma once #include "../Protocol.h" +#include "compat.h" #include #include #include +#if !defined(_WIN32) && !defined(_WIN64) +//NOP: linux isn't windows +#else #define WIN32_LEAN_AND_MEAN #include +#endif class ServerTrackedDeviceProvider; @@ -23,6 +28,9 @@ class IPCServer private: void HandleRequest(const protocol::Request &request, protocol::Response &response); +#if !defined(_WIN32) && !defined(_WIN64) + //NOP: Not used in Linux build +#else struct PipeInstance { OVERLAPPED overlap; // Used by the API @@ -35,19 +43,18 @@ class IPCServer PipeInstance *CreatePipeInstance(HANDLE pipe); void ClosePipeInstance(PipeInstance *pipeInst); - - static void RunThread(IPCServer *_this); - static BOOL CreateAndConnectInstance(LPOVERLAPPED overlap, HANDLE &pipe); static void WINAPI CompletedReadCallback(DWORD err, DWORD bytesRead, LPOVERLAPPED overlap); static void WINAPI CompletedWriteCallback(DWORD err, DWORD bytesWritten, LPOVERLAPPED overlap); + static BOOL CreateAndConnectInstance(LPOVERLAPPED overlap, HANDLE &pipe); + std::set pipes; + HANDLE connectEvent; +#endif + static void RunThread(IPCServer *_this); std::thread mainThread; bool running = false; bool stop = false; - std::set pipes; - HANDLE connectEvent; - ServerTrackedDeviceProvider *driver; }; diff --git a/OpenVR-SpaceCalibratorDriver/InterfaceHookInjector.cpp b/OpenVR-SpaceCalibratorDriver/InterfaceHookInjector.cpp index 62117463..21bbfa4d 100644 --- a/OpenVR-SpaceCalibratorDriver/InterfaceHookInjector.cpp +++ b/OpenVR-SpaceCalibratorDriver/InterfaceHookInjector.cpp @@ -1,8 +1,13 @@ #include "Logging.h" -#include "Hooking.h" #include "InterfaceHookInjector.h" #include "ServerTrackedDeviceProvider.h" +#include "Hooking.h" + +#if !defined(_WIN32) && !defined(_WIN64) +#include "compat.h" +#endif + static ServerTrackedDeviceProvider *Driver = nullptr; static Hook @@ -62,6 +67,7 @@ static void *DetourGetGenericInterface(vr::IVRDriverContext *_this, const char * void InjectHooks(ServerTrackedDeviceProvider *driver, vr::IVRDriverContext *pDriverContext) { + LOG("%s", "Injecting hooks"); Driver = driver; auto err = MH_Initialize(); @@ -79,5 +85,5 @@ void InjectHooks(ServerTrackedDeviceProvider *driver, vr::IVRDriverContext *pDri void DisableHooks() { IHook::DestroyAll(); - MH_Uninitialize(); -} \ No newline at end of file + MH_Uninitialize(); +} diff --git a/OpenVR-SpaceCalibratorDriver/Logging.cpp b/OpenVR-SpaceCalibratorDriver/Logging.cpp index 67b30778..0c3069b0 100644 --- a/OpenVR-SpaceCalibratorDriver/Logging.cpp +++ b/OpenVR-SpaceCalibratorDriver/Logging.cpp @@ -1,12 +1,13 @@ #define _CRT_SECURE_NO_DEPRECATE #include "Logging.h" #include +#include FILE *LogFile; void OpenLogFile() { - LogFile = fopen("space_calibrator_driver.log", "a"); + LogFile = fopen("/tmp/space_calibrator_driver.log", "w"); if (LogFile == nullptr) { LogFile = stderr; @@ -15,14 +16,20 @@ void OpenLogFile() tm TimeForLog() { + if(LogFile == nullptr){ + OpenLogFile(); + } + auto now = std::chrono::system_clock::now(); auto nowTime = std::chrono::system_clock::to_time_t(now); - tm value; - auto tm = localtime_s(&value, &nowTime); - return value; + tm buf; + auto tm = localtime_r(&nowTime, &buf); + return *tm; } + + void LogFlush() { fflush(LogFile); -} \ No newline at end of file +} diff --git a/OpenVR-SpaceCalibratorDriver/Logging.h b/OpenVR-SpaceCalibratorDriver/Logging.h index 5ecb9ded..88ce0a0b 100644 --- a/OpenVR-SpaceCalibratorDriver/Logging.h +++ b/OpenVR-SpaceCalibratorDriver/Logging.h @@ -17,7 +17,7 @@ void LogFlush(); } while (0) #endif -#define TRACE(...) {} +//#define TRACE(...) {} #ifndef TRACE #define TRACE LOG diff --git a/OpenVR-SpaceCalibratorDriver/OpenVR-SpaceCalibratorDriver.h b/OpenVR-SpaceCalibratorDriver/OpenVR-SpaceCalibratorDriver.h index 42b3263e..3fb133ec 100644 --- a/OpenVR-SpaceCalibratorDriver/OpenVR-SpaceCalibratorDriver.h +++ b/OpenVR-SpaceCalibratorDriver/OpenVR-SpaceCalibratorDriver.h @@ -1,7 +1,20 @@ #pragma once #ifdef OPENVRSPACECALIBRATORDRIVER_EXPORTS + +#if !defined(_WIN32) && !defined(_WIN64) +#define OPENVRSPACECALIBRATORDRIVER_API extern "C" +#else #define OPENVRSPACECALIBRATORDRIVER_API extern "C" __declspec(dllexport) +#endif + +#else + +#if !defined(_WIN32) && !defined(_WIN64) +#pragma warn "Linux not implimented" +#define OPENVRSPACECALIBRATORDRIVER_API extern "C" #else #define OPENVRSPACECALIBRATORDRIVER_API extern "C" __declspec(dllimport) #endif + +#endif diff --git a/OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.cpp b/OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.cpp index 55b09512..271efeeb 100644 --- a/OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.cpp +++ b/OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.cpp @@ -1,13 +1,33 @@ #include "ServerTrackedDeviceProvider.h" #include "Logging.h" #include "InterfaceHookInjector.h" +#include +#include + +#if !defined(_WIN32) && !defined(_WIN64) +#include +static void loopBreak(){ + volatile bool loop = true; + int pid = getpid(); + LOG("PID %d", pid); + while(loop){ + usleep(1000 * 1000); + } +} +#endif + + vr::EVRInitError ServerTrackedDeviceProvider::Init(vr::IVRDriverContext *pDriverContext) { - TRACE("ServerTrackedDeviceProvider::Init()"); + + //LOG("%s", "Starting loop break"); + //loopBreak(); + + TRACE("%s", "ServerTrackedDeviceProvider::Init()"); VR_INIT_SERVER_DRIVER_CONTEXT(pDriverContext); - memset(transforms, 0, vr::k_unMaxTrackedDeviceCount * sizeof DeviceTransform); + memset(transforms, 0, vr::k_unMaxTrackedDeviceCount * sizeof(DeviceTransform)); InjectHooks(this, pDriverContext); server.Run(); @@ -17,7 +37,7 @@ vr::EVRInitError ServerTrackedDeviceProvider::Init(vr::IVRDriverContext *pDriver void ServerTrackedDeviceProvider::Cleanup() { - TRACE("ServerTrackedDeviceProvider::Cleanup()"); + TRACE("%s", "ServerTrackedDeviceProvider::Cleanup()"); server.Stop(); DisableHooks(); VR_CLEANUP_SERVER_DRIVER_CONTEXT(); diff --git a/OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.h b/OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.h index 04e2edd8..da348dc3 100644 --- a/OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.h +++ b/OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.h @@ -16,21 +16,21 @@ class ServerTrackedDeviceProvider : public vr::IServerTrackedDeviceProvider virtual void Cleanup() override; /** Returns the version of the ITrackedDeviceServerDriver interface used by this driver */ - virtual const char * const *GetInterfaceVersions() { return vr::k_InterfaceVersions; } + virtual const char * const *GetInterfaceVersions() override { return vr::k_InterfaceVersions; } /** Allows the driver do to some work in the main loop of the server. */ - virtual void RunFrame() { } + virtual void RunFrame() override { } /** Returns true if the driver wants to block Standby mode. */ - virtual bool ShouldBlockStandbyMode() { return false; } + virtual bool ShouldBlockStandbyMode() override { return false; } /** Called when the system is entering Standby mode. The driver should switch itself into whatever sort of low-power * state it has. */ - virtual void EnterStandby() { } + virtual void EnterStandby() override { } /** Called when the system is leaving Standby mode. The driver should switch itself back to full operation. */ - virtual void LeaveStandby() { } + virtual void LeaveStandby() override { } ////// End vr::IServerTrackedDeviceProvider functions @@ -50,4 +50,4 @@ class ServerTrackedDeviceProvider : public vr::IServerTrackedDeviceProvider }; DeviceTransform transforms[vr::k_unMaxTrackedDeviceCount]; -}; \ No newline at end of file +}; diff --git a/OpenVR-SpaceCalibratorDriver/build.sh b/OpenVR-SpaceCalibratorDriver/build.sh new file mode 100755 index 00000000..da379f0c --- /dev/null +++ b/OpenVR-SpaceCalibratorDriver/build.sh @@ -0,0 +1,24 @@ +#!/bin/bash - + +set -o nounset # Treat unset variables as an error + +g++ --std=c++11 -D__linux__ -g \ + IPCServer.cpp \ + InterfaceHookInjector.cpp \ + Logging.cpp \ + OpenVR-SpaceCalibratorDriver.cpp \ + ServerTrackedDeviceProvider.cpp \ + compat.cpp \ + dllmain.cpp \ + Hooking.cpp \ + subhook.a \ + -masm=intel \ + -fPIC -shared \ + -o 01spacecalibrator/bin/linux64/driver_01spacecalibrator.so \ + -isystem /home/zack/src/openvr/headers \ + -isystem $PWD/../modules/subhook/ + +#-Wall -Wextra \ +#cp ../modules/subhook/build/libsubhook.so ./01spacecalibrator/bin/linux64/ + + diff --git a/OpenVR-SpaceCalibratorDriver/compat.cpp b/OpenVR-SpaceCalibratorDriver/compat.cpp new file mode 100644 index 00000000..2015ebcd --- /dev/null +++ b/OpenVR-SpaceCalibratorDriver/compat.cpp @@ -0,0 +1,43 @@ +#include +#include "compat.h" +#include + +std::unordered_map functionMap; + + +void MessageBox(void *, wchar_t const * msg, wchar_t const * title, int /* trash */ ){ + std::cerr << "Messagebox: " << title << ": " << msg << std::endl; +} + +/* +void MessageBox(void *, char* msg, char * title, int ){ + std::cerr << "Messagebox: " << title << ": " << msg << std::endl; +} */ + + +int MH_Initialize(){ + return 0; +} + +char const * MH_StatusToString(int err){ + switch(err){ + case 0: + return "No Error"; + default: + return "Unkonwn"; + } +} + +void MH_Uninitialize() +{ +} + +void MH_RemoveHook(void* thing){ +} +int MH_EnableHook(void* thing){ + return 1; +} +int MH_CreateHook(void* a, void* b, LPVOID* fun){ + return 1; +} + diff --git a/OpenVR-SpaceCalibratorDriver/compat.h b/OpenVR-SpaceCalibratorDriver/compat.h new file mode 100644 index 00000000..e0c0e680 --- /dev/null +++ b/OpenVR-SpaceCalibratorDriver/compat.h @@ -0,0 +1,44 @@ +#pragma once + +#if !defined(_WIN32) && !defined(_WIN64) + +#include + +#define WINAPI +typedef void* LPVOID; + + +typedef struct _OVERLAPPED { + void * nothing; +} OVERLAPPED; + +typedef void* HANDLE; +typedef bool BOOL; +typedef uint32_t DWORD; +typedef OVERLAPPED* LPOVERLAPPED; +typedef unsigned char BYTE; +typedef int LSTATUS; +typedef wchar_t * LPWSTR; + +#define MAX_PATH 1024 + +#define MH_OK 0 +#define FALSE false +#define TRUE true + +#define ERROR_BROKEN_PIPE 1 +#define ERROR_SUCCESS 0 +#define INVALID_HANDLE_VALUE nullptr + +void MessageBox(void *, wchar_t const * msg, wchar_t const * title, int trash); + +int MH_Initialize(); +char const * MH_StatusToString(int err); +void MH_Uninitialize(); +void MH_RemoveHook(void* thing); +int MH_EnableHook(void* thing); +int MH_CreateHook(void* a, void* b, LPVOID* fun); + +#else +//NOP not needed in windows +#endif diff --git a/OpenVR-SpaceCalibratorDriver/dllmain.cpp b/OpenVR-SpaceCalibratorDriver/dllmain.cpp index 21ccf7c5..06d7d893 100644 --- a/OpenVR-SpaceCalibratorDriver/dllmain.cpp +++ b/OpenVR-SpaceCalibratorDriver/dllmain.cpp @@ -1,6 +1,24 @@ #include "Logging.h" #include "../Version.h" +#if !defined(_WIN32) && !defined(_WIN64) +#include + +__attribute__((constructor)) +static void loaded(){ + int pid = getpid(); + LOG("OpenVR-SpaceCalibratorDriver " SPACECAL_VERSION_STRING " loaded into pid %d", pid); +} + +__attribute__((destructor)) +static void unloaded(){ + int pid = getpid(); + LOG("OpenVR-SpaceCalibratorDriver " SPACECAL_VERSION_STRING " unloaded from pid %d", pid); +} + + + +#else #define WIN32_LEAN_AND_MEAN #include #include @@ -23,3 +41,4 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv return TRUE; } +#endif diff --git a/Protocol.h b/Protocol.h index ff0b8e7a..b565a584 100644 --- a/Protocol.h +++ b/Protocol.h @@ -8,6 +8,10 @@ #define OPENVR_SPACECALIBRATOR_PIPE_NAME "\\\\.\\pipe\\OpenVRSpaceCalibratorDriver" + +#define COMM_PORT_SERVER 5473 +#define COMM_PORT_CLIENT 5474 + namespace protocol { const uint32_t Version = 2; @@ -42,23 +46,23 @@ namespace protocol vr::HmdQuaternion_t rotation; double scale; - SetDeviceTransform(uint32_t id, bool enabled) : - openVRID(id), enabled(enabled), updateTranslation(false), updateRotation(false), updateScale(false) { } + SetDeviceTransform(uint32_t id, bool _enabled) : + openVRID(id), enabled(_enabled), updateTranslation(false), updateRotation(false), updateScale(false) { } - SetDeviceTransform(uint32_t id, bool enabled, vr::HmdVector3d_t translation) : - openVRID(id), enabled(enabled), updateTranslation(true), updateRotation(false), updateScale(false), translation(translation) { } + SetDeviceTransform(uint32_t id, bool _enabled, vr::HmdVector3d_t _translation) : + openVRID(id), enabled(_enabled), updateTranslation(true), updateRotation(false), updateScale(false), translation(_translation) { } - SetDeviceTransform(uint32_t id, bool enabled, vr::HmdQuaternion_t rotation) : - openVRID(id), enabled(enabled), updateTranslation(false), updateRotation(true), updateScale(false), rotation(rotation) { } + SetDeviceTransform(uint32_t id, bool _enabled, vr::HmdQuaternion_t _rotation) : + openVRID(id), enabled(_enabled), updateTranslation(false), updateRotation(true), updateScale(false), rotation(_rotation) { } - SetDeviceTransform(uint32_t id, bool enabled, double scale) : - openVRID(id), enabled(enabled), updateTranslation(false), updateRotation(false), updateScale(true), scale(scale) { } + SetDeviceTransform(uint32_t id, bool _enabled, double _scale) : + openVRID(id), enabled(_enabled), updateTranslation(false), updateRotation(false), updateScale(true), scale(_scale) { } - SetDeviceTransform(uint32_t id, bool enabled, vr::HmdVector3d_t translation, vr::HmdQuaternion_t rotation) : - openVRID(id), enabled(enabled), updateTranslation(true), updateRotation(true), updateScale(false), translation(translation), rotation(rotation) { } + SetDeviceTransform(uint32_t id, bool _enabled, vr::HmdVector3d_t _translation, vr::HmdQuaternion_t _rotation) : + openVRID(id), enabled(_enabled), updateTranslation(true), updateRotation(true), updateScale(false), translation(_translation), rotation(_rotation) { } - SetDeviceTransform(uint32_t id, bool enabled, vr::HmdVector3d_t translation, vr::HmdQuaternion_t rotation, double scale) : - openVRID(id), enabled(enabled), updateTranslation(true), updateRotation(true), updateScale(true), translation(translation), rotation(rotation), scale(scale) { } + SetDeviceTransform(uint32_t id, bool _enabled, vr::HmdVector3d_t _translation, vr::HmdQuaternion_t _rotation, double _scale) : + openVRID(id), enabled(_enabled), updateTranslation(true), updateRotation(true), updateScale(true), translation(_translation), rotation(_rotation), scale(_scale) { } }; struct Request @@ -70,7 +74,7 @@ namespace protocol }; Request() : type(RequestInvalid) { } - Request(RequestType type) : type(type) { } + Request(RequestType _type) : type(_type) { } }; struct Response @@ -82,6 +86,6 @@ namespace protocol }; Response() : type(ResponseInvalid) { } - Response(ResponseType type) : type(type) { } + Response(ResponseType _type) : type(_type) { } }; -} \ No newline at end of file +} diff --git a/Version.h b/Version.h index 281e1715..4a569578 100644 --- a/Version.h +++ b/Version.h @@ -1,3 +1,7 @@ #pragma once -#define SPACECAL_VERSION_STRING "1.4" \ No newline at end of file +#if !defined(_WIN32) && !defined(_WIN64) +#define SPACECAL_VERSION_STRING "1.4-LINUX" +#else +#define SPACECAL_VERSION_STRING "1.4" +#endif diff --git a/modules/gl3w b/modules/gl3w new file mode 160000 index 00000000..5f8d7fd1 --- /dev/null +++ b/modules/gl3w @@ -0,0 +1 @@ +Subproject commit 5f8d7fd191ba22ff2b60c1106d7135bb9a335533 diff --git a/modules/imgui b/modules/imgui new file mode 160000 index 00000000..cdebd70e --- /dev/null +++ b/modules/imgui @@ -0,0 +1 @@ +Subproject commit cdebd70e15f57eb455485a50acb25ebc8787ab78 From d23704e15d6e5a9412ab5dbca0113c0eb0d06f16 Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Mon, 29 Aug 2022 00:21:14 -0500 Subject: [PATCH 02/27] Added CMake & openvr --- .gitignore | 1 + .gitmodules | 3 +++ CMakeLists.txt | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++ modules/openvr | 1 + 4 files changed, 77 insertions(+) create mode 100644 CMakeLists.txt create mode 160000 modules/openvr diff --git a/.gitignore b/.gitignore index 577fa362..64b92871 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ ipch *.srctrlbm *.out OpenVR-SpaceCalibratorDriver/01spacecalibrator/bin/linux64/ +build diff --git a/.gitmodules b/.gitmodules index c052ab37..92ab6a3c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [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 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..d16fcdba --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,72 @@ +cmake_minimum_required(VERSION 3.10) + +project (OpenVR-SpaceCalibrator VERSION 1.0) +add_definitions(-D__linux__) + +#add_executable(SpaceCalibrator "${OpenVR-SpaceCalibrator}") +#target_include_directories(SpaceCalibrator PUBLIC "OpenVR-SpaceCalibratorDriver") +#find_library( OpenVR NAMES libopenvr_api PATHS "./modules/openvr/bin/linux64/libopenvr_api.so") + +add_library(libopenvr_api SHARED IMPORTED) +set_target_properties(libopenvr_api PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/modules/openvr/bin/linux64/libopenvr_api.so) + +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) + +include_directories(OpenVR-SpaceCalibratorDriver) +include_directories(/usr/include/eigen3) +include_directories(lib/gl3w/include) +include_directories(lib) +include_directories(modules/openvr/headers) +include_directories(modules/glfw/include) + +add_library(gl3w modules/gl3w/build/src/gl3w.c) + +#add_executable(driver_01spacecalibrator.so OpenVR-SpaceCalibratorDriver/OpenVR-SpaceCalibratorDriver.cpp) + +#configure_file(LinixConfig.h.in LinuxConfig.h) + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +add_executable(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(SpaceCalibrator PRIVATE libopenvr_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 "" +) diff --git a/modules/openvr b/modules/openvr new file mode 160000 index 00000000..08de3821 --- /dev/null +++ b/modules/openvr @@ -0,0 +1 @@ +Subproject commit 08de3821dfd3aa46f778376680c68f33b9fdcb6c From ab9f0e5b98221608621bdd9c23bd8c02a5c91723 Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Mon, 29 Aug 2022 06:13:58 -0500 Subject: [PATCH 03/27] Cleaning up build --- .gitmodules | 3 --- CMakeLists.txt | 14 +++----------- modules/openvr | 1 - 3 files changed, 3 insertions(+), 15 deletions(-) delete mode 160000 modules/openvr diff --git a/.gitmodules b/.gitmodules index 92ab6a3c..c052ab37 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,6 +7,3 @@ [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 diff --git a/CMakeLists.txt b/CMakeLists.txt index d16fcdba..c0e28208 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,13 +3,6 @@ cmake_minimum_required(VERSION 3.10) project (OpenVR-SpaceCalibrator VERSION 1.0) add_definitions(-D__linux__) -#add_executable(SpaceCalibrator "${OpenVR-SpaceCalibrator}") -#target_include_directories(SpaceCalibrator PUBLIC "OpenVR-SpaceCalibratorDriver") -#find_library( OpenVR NAMES libopenvr_api PATHS "./modules/openvr/bin/linux64/libopenvr_api.so") - -add_library(libopenvr_api SHARED IMPORTED) -set_target_properties(libopenvr_api PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/modules/openvr/bin/linux64/libopenvr_api.so) - add_library(imgui lib/imgui/imgui.cpp lib/imgui/imgui_demo.cpp @@ -21,9 +14,11 @@ add_library(imgui find_library(glfw libglfw.so) find_library(GL libgl.so) +find_library(openvr_api openvr_api.so) include_directories(OpenVR-SpaceCalibratorDriver) include_directories(/usr/include/eigen3) +include_directories(/usr/include/openvr) include_directories(lib/gl3w/include) include_directories(lib) include_directories(modules/openvr/headers) @@ -31,8 +26,6 @@ include_directories(modules/glfw/include) add_library(gl3w modules/gl3w/build/src/gl3w.c) -#add_executable(driver_01spacecalibrator.so OpenVR-SpaceCalibratorDriver/OpenVR-SpaceCalibratorDriver.cpp) - #configure_file(LinixConfig.h.in LinuxConfig.h) set(CMAKE_CXX_STANDARD 14) @@ -50,8 +43,7 @@ add_executable(SpaceCalibrator ./OpenVR-SpaceCalibratorDriver/compat.cpp ./OpenVR-SpaceCalibratorDriver/Logging.cpp ) -TARGET_LINK_LIBRARIES(SpaceCalibrator PRIVATE libopenvr_api imgui gl3w GL glfw) - +TARGET_LINK_LIBRARIES(SpaceCalibrator PRIVATE openvr_api imgui gl3w GL glfw) add_library( driver_01spacecalibrator diff --git a/modules/openvr b/modules/openvr deleted file mode 160000 index 08de3821..00000000 --- a/modules/openvr +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 08de3821dfd3aa46f778376680c68f33b9fdcb6c From 8c1108989f0d452f0ac6751f61dca4da9d857e53 Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Mon, 29 Aug 2022 10:14:15 -0500 Subject: [PATCH 04/27] CMake improvements --- CMakeLists.txt | 6 ++- OpenVR-SpaceCalibrator/makefile | 78 --------------------------------- 2 files changed, 4 insertions(+), 80 deletions(-) delete mode 100644 OpenVR-SpaceCalibrator/makefile diff --git a/CMakeLists.txt b/CMakeLists.txt index c0e28208..38696cc6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ add_library(gl3w modules/gl3w/build/src/gl3w.c) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED True) -add_executable(SpaceCalibrator +add_executable(OpenVR-SpaceCalibrator OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp OpenVR-SpaceCalibrator/Calibration.cpp OpenVR-SpaceCalibrator/Configuration.cpp @@ -43,7 +43,7 @@ add_executable(SpaceCalibrator ./OpenVR-SpaceCalibratorDriver/compat.cpp ./OpenVR-SpaceCalibratorDriver/Logging.cpp ) -TARGET_LINK_LIBRARIES(SpaceCalibrator PRIVATE openvr_api imgui gl3w GL glfw) +TARGET_LINK_LIBRARIES(OpenVR-SpaceCalibrator PRIVATE openvr_api imgui gl3w GL glfw) add_library( driver_01spacecalibrator @@ -62,3 +62,5 @@ set_target_properties(driver_01spacecalibrator PROPERTIES OUTPUT_NAME driver_01spacecalibrator PREFIX "" ) + +configure_file( ./OpenVR-SpaceCalibrator/manifest.vrmanifest manifest.vrmanifest ) diff --git a/OpenVR-SpaceCalibrator/makefile b/OpenVR-SpaceCalibrator/makefile deleted file mode 100644 index 6c91937f..00000000 --- a/OpenVR-SpaceCalibrator/makefile +++ /dev/null @@ -1,78 +0,0 @@ -OFLAGS = -CC=g++ -STD=-std=c++14 -SHARED_FLAGS= -g -W -Wall -Wextra $(STD) -Wno-missing-field-initializers -Wshadow \ --I ../OpenVR-SpaceCalibratorDriver/ \ --isystem /usr/include/eigen3/ \ --isystem /home/zack/src/openvr/headers \ --isystem ../gl3w/build/include \ --isystem ../modules/gl3w/build/include \ --isystem ../lib/ \ -$(OFLAGS) - -CFLAGS=-c $(SHARED_FLAGS) - -LFLAGS= -g $(STD) $(OFLAGS) \ - -L /home/zack/src/openvr/lib/linux64 \ - -lGL -limgui -lopenvr_api -lglfw - -.PHONY:clean - -Objects=Calibration.o Configuration.o EmbeddedFiles.o IPCClient.o OpenVR-SpaceCalibrator.o UserInterface.o stdafx.o -Copy=gl3w.o imgui_impl_glfw.o imgui.a Logging.o compat.o - -all : $(Objects) spaceCal - -spaceCal : $(Objects) $(Copy) - $(CC) $(Std) $(Objects) $(Copy) $(LFLAGS) -o spaceCal - -$(Objects): %.o: %.cpp - $(CC) $(CFLAGS) $< - -gl3w.o: ../modules/gl3w/build/src/gl3w.c - $(CC) $(CFLAGS) ../modules/gl3w/build/src/gl3w.c -o gl3w.o - -imgui_impl_glfw.o: ../modules/imgui/backends/imgui_impl_glfw.cpp - $(CC) $(CFLAGS) ../modules/imgui/backends/imgui_impl_glfw.cpp -o imgui_impl_glfw.o - -imgui.a: ../lib/imgui/*cpp - rm -f imgui.a - $(CC) $(CFLAGS) ../lib/imgui/imgui.cpp - $(CC) $(CFLAGS) ../lib/imgui/imgui_demo.cpp - $(CC) $(CFLAGS) ../lib/imgui/imgui_draw.cpp - $(CC) $(CFLAGS) ../lib/imgui/imgui_impl_glfw.cpp - $(CC) $(CFLAGS) ../lib/imgui/imgui_impl_opengl3.cpp - ar rcs imgui.a imgui.o imgui_demo.o imgui_draw.o imgui_impl_glfw.o imgui_impl_opengl3.o - -Logging.o: ../OpenVR-SpaceCalibratorDriver/Logging.cpp - $(CC) $(CFLAGS) ../OpenVR-SpaceCalibratorDriver/Logging.cpp -o Logging.o - -compat.o: ../OpenVR-SpaceCalibratorDriver/compat.cpp - $(CC) $(CFLAGS) ../OpenVR-SpaceCalibratorDriver/compat.cpp -o compat.o - -dbg: spaceCal - gdb spaceCal - -run: spaceCal - ./spaceCal - -time: spaceCal - time ./spaceCal - -cache: spaceCal - rm c*grind* -f - valgrind --tool=cachegrind ./spaceCal - -call: spaceCal - rm c*grind* -f - valgrind --tool=callgrind --collect-jumps=yes --dump-instr=yes ./spaceCal - -inspect: - kcachegrind c*grind\.out\.* - -clean: - rm -f *o - rm -f imgui.a - rm -f spaceCal - rm -f c*grind\.out\.* - From 095b33535bb32079b45ec611bdb5883c9c1600fa Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Mon, 29 Aug 2022 10:20:35 -0500 Subject: [PATCH 05/27] Updating manifest handling --- .../OpenVR-SpaceCalibrator.cpp | 32 +++++++++++++------ OpenVR-SpaceCalibrator/manifest.vrmanifest | 2 +- OpenVR-SpaceCalibratorDriver/compat.cpp | 2 +- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp index 923474ae..e36192a5 100644 --- a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp +++ b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp @@ -39,6 +39,13 @@ extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001; #endif +#if !defined(_WIN32) && !defined(_WIN64) +#define MANIFEST_END_PATH "/manifest.vrmanifest" +#else +#define MANIFEST_END_PATH "\\manifest.vrmanifest" +#endif + + //#define DEBUG_LOGS #ifdef DEBUG_LOGS void CreateConsole() @@ -376,12 +383,7 @@ std::wstring to_wstring(std::string str) #if !defined(_WIN32) && !defined(_WIN64) int main(int argc, char ** argv) -#else -int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) -#endif { - -#if !defined(_WIN32) && !defined(_WIN64) wchar_t const * lpCmdLine; std::wstring wide; for(int i=1; iRemoveApplicationManifest(manifestPath.c_str()); } } std::string manifestPath = cwd; - manifestPath += "\\manifest.vrmanifest"; + manifestPath += MANIFEST_END_PATH; std::cout << "Adding manifest path: " << manifestPath << std::endl; auto vrAppErr = vr::VRApplications()->AddApplicationManifest(manifestPath.c_str()); if (vrAppErr != vr::VRApplicationError_None) @@ -532,7 +546,7 @@ static void HandleCommandLine(LPWSTR lpCmdLine) if (vr::VRApplications()->IsApplicationInstalled(OPENVR_APPLICATION_KEY)) { std::string manifestPath = cwd; - manifestPath += "\\manifest.vrmanifest"; + manifestPath += MANIFEST_END_PATH; std::cout << "Removing manifest path: " << manifestPath << std::endl; vr::VRApplications()->RemoveApplicationManifest(manifestPath.c_str()); } diff --git a/OpenVR-SpaceCalibrator/manifest.vrmanifest b/OpenVR-SpaceCalibrator/manifest.vrmanifest index 14cd0ad5..566da16b 100644 --- a/OpenVR-SpaceCalibrator/manifest.vrmanifest +++ b/OpenVR-SpaceCalibrator/manifest.vrmanifest @@ -13,4 +13,4 @@ } } }] -} \ No newline at end of file +} diff --git a/OpenVR-SpaceCalibratorDriver/compat.cpp b/OpenVR-SpaceCalibratorDriver/compat.cpp index 2015ebcd..ed0308d6 100644 --- a/OpenVR-SpaceCalibratorDriver/compat.cpp +++ b/OpenVR-SpaceCalibratorDriver/compat.cpp @@ -6,7 +6,7 @@ std::unordered_map functionMap; void MessageBox(void *, wchar_t const * msg, wchar_t const * title, int /* trash */ ){ - std::cerr << "Messagebox: " << title << ": " << msg << std::endl; + std::wcerr << "Messagebox: " << title << ": " << msg << std::endl; } /* From fddc727a5d7a12fff71d3a08a27d7cf1d1abf19b Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Mon, 29 Aug 2022 10:50:35 -0500 Subject: [PATCH 06/27] Improved gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 64b92871..9e868919 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ ipch *.out OpenVR-SpaceCalibratorDriver/01spacecalibrator/bin/linux64/ build +*.gitignore From a6081d6ae8fdfd2b23359fe0d649f586e2bd267a Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Mon, 29 Aug 2022 11:16:25 -0500 Subject: [PATCH 07/27] Swaping out verbose preprocessor platform checks --- OpenVR-SpaceCalibrator/Configuration.cpp | 6 +++--- OpenVR-SpaceCalibrator/IPCClient.cpp | 10 +++++----- OpenVR-SpaceCalibrator/IPCClient.h | 4 ++-- .../OpenVR-SpaceCalibrator.cpp | 18 +++++++++--------- OpenVR-SpaceCalibrator/stdafx.h | 2 +- OpenVR-SpaceCalibrator/targetver.h | 2 +- OpenVR-SpaceCalibratorDriver/Hooking.h | 6 +++--- OpenVR-SpaceCalibratorDriver/IPCServer.cpp | 10 +++++----- OpenVR-SpaceCalibratorDriver/IPCServer.h | 4 ++-- .../InterfaceHookInjector.cpp | 2 +- .../OpenVR-SpaceCalibratorDriver.h | 5 ++--- .../ServerTrackedDeviceProvider.cpp | 14 -------------- OpenVR-SpaceCalibratorDriver/compat.h | 2 +- OpenVR-SpaceCalibratorDriver/dllmain.cpp | 2 +- 14 files changed, 36 insertions(+), 51 deletions(-) diff --git a/OpenVR-SpaceCalibrator/Configuration.cpp b/OpenVR-SpaceCalibrator/Configuration.cpp index fa1109af..17470a5d 100644 --- a/OpenVR-SpaceCalibrator/Configuration.cpp +++ b/OpenVR-SpaceCalibrator/Configuration.cpp @@ -142,7 +142,7 @@ static void WriteProfile(CalibrationContext &ctx, std::ostream &out) out << profilesV.serialize(true); } -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ // NOP #else static const char *RegistryKey = "Software\\OpenVR-SpaceCalibrator"; @@ -156,7 +156,7 @@ static void LogRegistryResult(LSTATUS result) static std::string ReadRegistryKey() { -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ FILE* file = fopen(LINUX_CONFIG_FILE, "r"); if(!file) return ""; @@ -200,7 +200,7 @@ static std::string ReadRegistryKey() static void WriteRegistryKey(std::string str) { -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ FILE* file = fopen(LINUX_CONFIG_FILE, "w"); if(!file) std::cerr << "Error opening config file for writing"; diff --git a/OpenVR-SpaceCalibrator/IPCClient.cpp b/OpenVR-SpaceCalibrator/IPCClient.cpp index 7e51236f..0f824b6e 100644 --- a/OpenVR-SpaceCalibrator/IPCClient.cpp +++ b/OpenVR-SpaceCalibrator/IPCClient.cpp @@ -4,7 +4,7 @@ #include -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ // NOP #else static std::string LastErrorString(DWORD lastError) @@ -23,7 +23,7 @@ static std::string LastErrorString(DWORD lastError) IPCClient::~IPCClient() { -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ //NOP #else if (pipe && pipe != INVALID_HANDLE_VALUE) @@ -33,7 +33,7 @@ IPCClient::~IPCClient() void IPCClient::Connect() { -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ #else LPTSTR pipeName = TEXT(OPENVR_SPACECALIBRATOR_PIPE_NAME); @@ -72,7 +72,7 @@ protocol::Response IPCClient::SendBlocking(const protocol::Request &request) void IPCClient::Send(const protocol::Request &request) { -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ pipe.Send(request); #else DWORD bytesWritten; @@ -87,7 +87,7 @@ void IPCClient::Send(const protocol::Request &request) protocol::Response IPCClient::Receive() { protocol::Response response(protocol::ResponseInvalid); -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ pipe.Recv(&response); return response; #else diff --git a/OpenVR-SpaceCalibrator/IPCClient.h b/OpenVR-SpaceCalibrator/IPCClient.h index c525b9df..e2479c09 100644 --- a/OpenVR-SpaceCalibrator/IPCClient.h +++ b/OpenVR-SpaceCalibrator/IPCClient.h @@ -1,6 +1,6 @@ #pragma once -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ #include "compat.h" #include "Comms.h" #else @@ -20,7 +20,7 @@ class IPCClient protocol::Response Receive(); private: -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ Client pipe; #else HANDLE pipe = INVALID_HANDLE_VALUE; diff --git a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp index e36192a5..daf40a75 100644 --- a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp +++ b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp @@ -9,7 +9,7 @@ #include #include -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ #include #else #include @@ -23,7 +23,7 @@ #include #include -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ //NOP #else #pragma comment(linker,"\"/manifestdependency:type='win32' \ @@ -33,13 +33,13 @@ processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") #define OPENVR_APPLICATION_KEY "pushrax.SpaceCalibrator" -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ #else extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001; #endif -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ #define MANIFEST_END_PATH "/manifest.vrmanifest" #else #define MANIFEST_END_PATH "\\manifest.vrmanifest" @@ -72,7 +72,7 @@ void openGLDebugCallback(GLenum /* source */, GLenum /* type */, GLuint id, GLen { fprintf(stderr, "OpenGL Debug %u: %.*s\n", id, length, message); } -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ static void HandleCommandLine(wchar_t const * lpCmdLine); #else static void HandleCommandLine(LPWSTR lpCmdLine); @@ -381,7 +381,7 @@ std::wstring to_wstring(std::string str) return strconverter.from_bytes(str); } -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ int main(int argc, char ** argv) { wchar_t const * lpCmdLine; @@ -447,13 +447,13 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance glfwTerminate(); return 0; } -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ bool StringMatch(wchar_t const * first, wchar_t const * second) { #else bool StringMatch(LPWSTR first, LPWSTR second) { #endif bool ret; -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ ret = wcscmp(first, second) == 0; #else ret = lstrcmp(first, second) == 0; @@ -461,7 +461,7 @@ bool StringMatch(LPWSTR first, LPWSTR second) { return ret; } -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ static void HandleCommandLine(wchar_t const * lpCmdLine) #else static void HandleCommandLine(LPWSTR lpCmdLine) diff --git a/OpenVR-SpaceCalibrator/stdafx.h b/OpenVR-SpaceCalibrator/stdafx.h index 76ab7157..0c0fa62b 100644 --- a/OpenVR-SpaceCalibrator/stdafx.h +++ b/OpenVR-SpaceCalibrator/stdafx.h @@ -1,6 +1,6 @@ #pragma once -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ #include #include "compat.h" diff --git a/OpenVR-SpaceCalibrator/targetver.h b/OpenVR-SpaceCalibrator/targetver.h index 774e8e24..0b7e2338 100644 --- a/OpenVR-SpaceCalibrator/targetver.h +++ b/OpenVR-SpaceCalibrator/targetver.h @@ -4,7 +4,7 @@ // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ // NOP: not in linux build #else #include diff --git a/OpenVR-SpaceCalibratorDriver/Hooking.h b/OpenVR-SpaceCalibratorDriver/Hooking.h index 3003aeb9..1c9a5d63 100644 --- a/OpenVR-SpaceCalibratorDriver/Hooking.h +++ b/OpenVR-SpaceCalibratorDriver/Hooking.h @@ -2,7 +2,7 @@ #include "Logging.h" -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ #include #include "string.h" #include @@ -39,7 +39,7 @@ template class Hook : public IHook FuncType originalFunc = nullptr; Hook(const std::string &name) : IHook(name) { } -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ template bool CreateHookInObjectVTable(void *object, int vtableOffset, T* detourFunction) { @@ -104,7 +104,7 @@ template class Hook : public IHook void Destroy() { -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ // should probably do something, but meh. #else if (enabled) diff --git a/OpenVR-SpaceCalibratorDriver/IPCServer.cpp b/OpenVR-SpaceCalibratorDriver/IPCServer.cpp index 4a98dc74..ebed1269 100644 --- a/OpenVR-SpaceCalibratorDriver/IPCServer.cpp +++ b/OpenVR-SpaceCalibratorDriver/IPCServer.cpp @@ -2,7 +2,7 @@ #include "Logging.h" #include "ServerTrackedDeviceProvider.h" -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ #include "Comms.h" #else @@ -46,7 +46,7 @@ void IPCServer::Stop() return; stop = true; -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ //NOP #else SetEvent(connectEvent); @@ -55,7 +55,7 @@ void IPCServer::Stop() TRACE("IPCServer::Stop() finished"); #endif } -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ //NOP #else IPCServer::PipeInstance *IPCServer::CreatePipeInstance(HANDLE pipe) @@ -78,7 +78,7 @@ void IPCServer::ClosePipeInstance(PipeInstance *pipeInst) void IPCServer::RunThread(IPCServer *_this) { -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ Comms comms; protocol::Response response; @@ -155,7 +155,7 @@ void IPCServer::RunThread(IPCServer *_this) #endif } -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ //NOP #else BOOL IPCServer::CreateAndConnectInstance(LPOVERLAPPED overlap, HANDLE &pipe) diff --git a/OpenVR-SpaceCalibratorDriver/IPCServer.h b/OpenVR-SpaceCalibratorDriver/IPCServer.h index 9d771c38..28805117 100644 --- a/OpenVR-SpaceCalibratorDriver/IPCServer.h +++ b/OpenVR-SpaceCalibratorDriver/IPCServer.h @@ -7,7 +7,7 @@ #include #include -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ //NOP: linux isn't windows #else #define WIN32_LEAN_AND_MEAN @@ -28,7 +28,7 @@ class IPCServer private: void HandleRequest(const protocol::Request &request, protocol::Response &response); -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ //NOP: Not used in Linux build #else struct PipeInstance diff --git a/OpenVR-SpaceCalibratorDriver/InterfaceHookInjector.cpp b/OpenVR-SpaceCalibratorDriver/InterfaceHookInjector.cpp index 21bbfa4d..9b744f9a 100644 --- a/OpenVR-SpaceCalibratorDriver/InterfaceHookInjector.cpp +++ b/OpenVR-SpaceCalibratorDriver/InterfaceHookInjector.cpp @@ -4,7 +4,7 @@ #include "Hooking.h" -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ #include "compat.h" #endif diff --git a/OpenVR-SpaceCalibratorDriver/OpenVR-SpaceCalibratorDriver.h b/OpenVR-SpaceCalibratorDriver/OpenVR-SpaceCalibratorDriver.h index 3fb133ec..ef06664b 100644 --- a/OpenVR-SpaceCalibratorDriver/OpenVR-SpaceCalibratorDriver.h +++ b/OpenVR-SpaceCalibratorDriver/OpenVR-SpaceCalibratorDriver.h @@ -2,7 +2,7 @@ #ifdef OPENVRSPACECALIBRATORDRIVER_EXPORTS -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ #define OPENVRSPACECALIBRATORDRIVER_API extern "C" #else #define OPENVRSPACECALIBRATORDRIVER_API extern "C" __declspec(dllexport) @@ -10,8 +10,7 @@ #else -#if !defined(_WIN32) && !defined(_WIN64) -#pragma warn "Linux not implimented" +#ifdef __linux__ #define OPENVRSPACECALIBRATORDRIVER_API extern "C" #else #define OPENVRSPACECALIBRATORDRIVER_API extern "C" __declspec(dllimport) diff --git a/OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.cpp b/OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.cpp index 271efeeb..3a98a71f 100644 --- a/OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.cpp +++ b/OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.cpp @@ -4,20 +4,6 @@ #include #include -#if !defined(_WIN32) && !defined(_WIN64) -#include -static void loopBreak(){ - volatile bool loop = true; - int pid = getpid(); - LOG("PID %d", pid); - while(loop){ - usleep(1000 * 1000); - } -} -#endif - - - vr::EVRInitError ServerTrackedDeviceProvider::Init(vr::IVRDriverContext *pDriverContext) { diff --git a/OpenVR-SpaceCalibratorDriver/compat.h b/OpenVR-SpaceCalibratorDriver/compat.h index e0c0e680..09717e32 100644 --- a/OpenVR-SpaceCalibratorDriver/compat.h +++ b/OpenVR-SpaceCalibratorDriver/compat.h @@ -1,6 +1,6 @@ #pragma once -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ #include diff --git a/OpenVR-SpaceCalibratorDriver/dllmain.cpp b/OpenVR-SpaceCalibratorDriver/dllmain.cpp index 06d7d893..90ee68d3 100644 --- a/OpenVR-SpaceCalibratorDriver/dllmain.cpp +++ b/OpenVR-SpaceCalibratorDriver/dllmain.cpp @@ -1,7 +1,7 @@ #include "Logging.h" #include "../Version.h" -#if !defined(_WIN32) && !defined(_WIN64) +#ifdef __linux__ #include __attribute__((constructor)) From 01442d24605d0a700d1c2d2d429c5ba40c6003cc Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Mon, 29 Aug 2022 23:09:45 -0500 Subject: [PATCH 08/27] Build fixes --- CMakeLists.txt | 1 + OpenVR-SpaceCalibrator/manifest.vrmanifest | 1 + OpenVR-SpaceCalibratorDriver/compat.cpp | 6 +++--- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 38696cc6..3148fe5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,3 +64,4 @@ set_target_properties(driver_01spacecalibrator PROPERTIES ) configure_file( ./OpenVR-SpaceCalibrator/manifest.vrmanifest manifest.vrmanifest ) +configure_file( ./OpenVR-SpaceCalibratorDriver/01spacecalibrator/driver.vrdrivermanifest driver.vrdrivermanifest ) diff --git a/OpenVR-SpaceCalibrator/manifest.vrmanifest b/OpenVR-SpaceCalibrator/manifest.vrmanifest index 566da16b..a3cfd3e7 100644 --- a/OpenVR-SpaceCalibrator/manifest.vrmanifest +++ b/OpenVR-SpaceCalibrator/manifest.vrmanifest @@ -4,6 +4,7 @@ "app_key": "pushrax.SpaceCalibrator", "launch_type": "binary", "binary_path_windows": "OpenVR-SpaceCalibrator.exe", + "binary_path_linux": "OpenVR-SpaceCalibrator", "is_dashboard_overlay": true, "strings": { diff --git a/OpenVR-SpaceCalibratorDriver/compat.cpp b/OpenVR-SpaceCalibratorDriver/compat.cpp index ed0308d6..5bc82aaa 100644 --- a/OpenVR-SpaceCalibratorDriver/compat.cpp +++ b/OpenVR-SpaceCalibratorDriver/compat.cpp @@ -32,12 +32,12 @@ void MH_Uninitialize() { } -void MH_RemoveHook(void* thing){ +void MH_RemoveHook(void* /* thing */){ } -int MH_EnableHook(void* thing){ +int MH_EnableHook(void* /* thing */){ return 1; } -int MH_CreateHook(void* a, void* b, LPVOID* fun){ +int MH_CreateHook(void* /* a */, void* /* b */, LPVOID* /* fun */){ return 1; } From 7f2e0410db614003fddec1a13b595cf06d373ab0 Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Tue, 30 Aug 2022 00:24:39 -0500 Subject: [PATCH 09/27] Fixing new clone build issue --- CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3148fe5b..996ca1ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,9 +22,8 @@ include_directories(/usr/include/openvr) include_directories(lib/gl3w/include) include_directories(lib) include_directories(modules/openvr/headers) -include_directories(modules/glfw/include) -add_library(gl3w modules/gl3w/build/src/gl3w.c) +add_library(gl3w lib/gl3w/src/gl3w.c) #configure_file(LinixConfig.h.in LinuxConfig.h) From bfa1c3e0649c2ad5c4b59fec3d5cb1268a416bdf Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Thu, 1 Sep 2022 22:10:29 -0500 Subject: [PATCH 10/27] Imporving initial build process on Linux Removing unused module Have CMake pull the submodules Added Linux CMake installer Removing unused code Partially working auto installer. --- .gitmodules | 6 +- CMakeLists.txt | 65 ++++++++++++++-- .../OpenVR-SpaceCalibrator.cpp | 74 ++++++++++++++++-- OpenVR-SpaceCalibratorDriver/Comms.h | 4 +- OpenVR-SpaceCalibratorDriver/Logging.cpp | 9 ++- OpenVR-SpaceCalibratorDriver/build.sh | 24 ------ StaticConfig.h.in | 4 + driverInstall.py | 76 +++++++++++++++++++ modules/gl3w | 1 - modules/openvr | 1 + 10 files changed, 219 insertions(+), 45 deletions(-) delete mode 100755 OpenVR-SpaceCalibratorDriver/build.sh create mode 100644 StaticConfig.h.in create mode 100755 driverInstall.py delete mode 160000 modules/gl3w create mode 160000 modules/openvr diff --git a/.gitmodules b/.gitmodules index c052ab37..e330450c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,9 @@ [submodule "OpenVR-SpaceCalibrator/gl3w"] path = OpenVR-SpaceCalibrator/gl3w url = https://github.com/skaslev/gl3w.git -[submodule "modules/gl3w"] - path = modules/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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 996ca1ff..9d0b9c82 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,9 @@ 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" ) + add_library(imgui lib/imgui/imgui.cpp lib/imgui/imgui_demo.cpp @@ -13,17 +16,16 @@ add_library(imgui ) find_library(glfw libglfw.so) -find_library(GL libgl.so) -find_library(openvr_api openvr_api.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(/usr/include/openvr) include_directories(lib/gl3w/include) include_directories(lib) include_directories(modules/openvr/headers) -add_library(gl3w lib/gl3w/src/gl3w.c) +add_library( gl3w lib/gl3w/src/gl3w.c ) #configure_file(LinixConfig.h.in LinuxConfig.h) @@ -62,5 +64,56 @@ set_target_properties(driver_01spacecalibrator PROPERTIES PREFIX "" ) -configure_file( ./OpenVR-SpaceCalibrator/manifest.vrmanifest manifest.vrmanifest ) -configure_file( ./OpenVR-SpaceCalibratorDriver/01spacecalibrator/driver.vrdrivermanifest driver.vrdrivermanifest ) +####################################################################################### +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() + diff --git a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp index daf40a75..ff581fb6 100644 --- a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp +++ b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include "GL/gl3w.h" #ifdef __linux__ #include @@ -24,7 +24,7 @@ #include #ifdef __linux__ -//NOP +#include "StaticConfig.h" #else #pragma comment(linker,"\"/manifestdependency:type='win32' \ name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ @@ -40,9 +40,9 @@ extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x #endif #ifdef __linux__ -#define MANIFEST_END_PATH "/manifest.vrmanifest" +#define MANIFEST_PATH(CWD) (APP_MANIFEST_PATH) #else -#define MANIFEST_END_PATH "\\manifest.vrmanifest" +#define MANIFEST_PATH(CWD) (CWD + "\\manifest.vrmanifest") #endif @@ -474,6 +474,10 @@ static void HandleCommandLine(LPWSTR lpCmdLine) std::cout << "-installmanifest install the application vrmanifest" << std::endl; std::cout << "-removemanifest remove the application vrmanifest" << std::endl; std::cout << "-activatemultipledrivers enable multiple drivers in steamvr" << std::endl; +#ifdef __linux__ + std::cout << "-installdriver install the steam vr driver." << std::endl; + std::cout << "-uninstalldriver uninstall the steam vr driver." << std::endl; +#endif std::cout << "-help -h print this message" << std::endl; exit(0); } @@ -513,13 +517,14 @@ static void HandleCommandLine(LPWSTR lpCmdLine) else { std::string manifestPath = oldWd; - manifestPath += MANIFEST_END_PATH; + manifestPath = MANIFEST_PATH(manifestPath); std::cout << "Removing old manifest path: " << manifestPath << std::endl; vr::VRApplications()->RemoveApplicationManifest(manifestPath.c_str()); } } std::string manifestPath = cwd; - manifestPath += MANIFEST_END_PATH; + manifestPath = MANIFEST_PATH(manifestPath); + std::cout << "Adding manifest path: " << manifestPath << std::endl; auto vrAppErr = vr::VRApplications()->AddApplicationManifest(manifestPath.c_str()); if (vrAppErr != vr::VRApplicationError_None) @@ -545,8 +550,9 @@ static void HandleCommandLine(LPWSTR lpCmdLine) { if (vr::VRApplications()->IsApplicationInstalled(OPENVR_APPLICATION_KEY)) { - std::string manifestPath = cwd; - manifestPath += MANIFEST_END_PATH; + std::string manifestPath = cwd; + manifestPath = MANIFEST_PATH(manifestPath); + std::cout << "Removing manifest path: " << manifestPath << std::endl; vr::VRApplications()->RemoveApplicationManifest(manifestPath.c_str()); } @@ -581,4 +587,56 @@ static void HandleCommandLine(LPWSTR lpCmdLine) vr::VR_Shutdown(); exit(ret); } +#ifdef __linux__ + else if (StringMatch(lpCmdLine, L"-installdriver")) + { + auto vrErr = vr::VRInitError_None; + vr::VR_Init(&vrErr, vr::VRApplication_Utility); + if (vrErr != vr::VRInitError_None) + { + fprintf(stderr, "Failed to initialize OpenVR: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(vrErr)); + vr::VR_Shutdown(); + exit(-2); + } + + char cruntimePath[MAX_PATH] = { 0 }; + unsigned int pathLen; + vr::VR_GetRuntimePath(cruntimePath, MAX_PATH, &pathLen); + + const int cmdLength = 8196; + char cmd[cmdLength]; + + snprintf(cmd, cmdLength, "python " DRIVER_INSTALLER_PATH "/driverInstall.py --toInstall " DRIVER_MANIFEST_PATH " --vrpathreg %s/bin/vrpathreg.sh", cruntimePath); + printf("cmd: %s\n", cmd); + system(cmd); + + vr::VR_Shutdown(); + exit(0); + } + else if (StringMatch(lpCmdLine, L"-uninstalldriver")) + { + auto vrErr = vr::VRInitError_None; + vr::VR_Init(&vrErr, vr::VRApplication_Utility); + if (vrErr != vr::VRInitError_None) + { + fprintf(stderr, "Failed to initialize OpenVR: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(vrErr)); + vr::VR_Shutdown(); + exit(-2); + } + + char cruntimePath[MAX_PATH] = { 0 }; + unsigned int pathLen; + vr::VR_GetRuntimePath(cruntimePath, MAX_PATH, &pathLen); + + const int cmdLength = 8196; + char cmd[cmdLength]; + + snprintf(cmd, cmdLength, "\"%s/bin/vrpathreg.sh\" removedriverwithname 01spacecalibrator", cruntimePath); + printf("cmd: %s\n", cmd); + + vr::VR_Shutdown(); + exit(0); + } +#endif + } diff --git a/OpenVR-SpaceCalibratorDriver/Comms.h b/OpenVR-SpaceCalibratorDriver/Comms.h index 9b59ff0b..2ead52c3 100644 --- a/OpenVR-SpaceCalibratorDriver/Comms.h +++ b/OpenVR-SpaceCalibratorDriver/Comms.h @@ -33,13 +33,13 @@ class UDPServerSocket{ //TODO verify that 0 is valid for UDP. sock = socket(AF_INET, SOCK_DGRAM, 0); if(sock == -1){ - LOG("%s", "Failed to create socket"); + LOG("Failed to create socket: %s", strerror(errno)); return false; } int err = bind(sock, (sockaddr*)&my_addr, sizeof(my_addr)); if(err){ - LOG("%s", "Failed to bind socket"); + LOG("Failed to bind socket: %s", strerror(errno)); return false; } return true; diff --git a/OpenVR-SpaceCalibratorDriver/Logging.cpp b/OpenVR-SpaceCalibratorDriver/Logging.cpp index 0c3069b0..c599ec44 100644 --- a/OpenVR-SpaceCalibratorDriver/Logging.cpp +++ b/OpenVR-SpaceCalibratorDriver/Logging.cpp @@ -3,11 +3,18 @@ #include #include +#ifdef __linux__ +#include "StaticConfig.h" +#else +#define DRIVER_LOG_FILE "space_calibrator_driver.log" +#endif + + FILE *LogFile; void OpenLogFile() { - LogFile = fopen("/tmp/space_calibrator_driver.log", "w"); + LogFile = fopen(DRIVER_LOG_FILE, "w"); if (LogFile == nullptr) { LogFile = stderr; diff --git a/OpenVR-SpaceCalibratorDriver/build.sh b/OpenVR-SpaceCalibratorDriver/build.sh deleted file mode 100755 index da379f0c..00000000 --- a/OpenVR-SpaceCalibratorDriver/build.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - - -set -o nounset # Treat unset variables as an error - -g++ --std=c++11 -D__linux__ -g \ - IPCServer.cpp \ - InterfaceHookInjector.cpp \ - Logging.cpp \ - OpenVR-SpaceCalibratorDriver.cpp \ - ServerTrackedDeviceProvider.cpp \ - compat.cpp \ - dllmain.cpp \ - Hooking.cpp \ - subhook.a \ - -masm=intel \ - -fPIC -shared \ - -o 01spacecalibrator/bin/linux64/driver_01spacecalibrator.so \ - -isystem /home/zack/src/openvr/headers \ - -isystem $PWD/../modules/subhook/ - -#-Wall -Wextra \ -#cp ../modules/subhook/build/libsubhook.so ./01spacecalibrator/bin/linux64/ - - diff --git a/StaticConfig.h.in b/StaticConfig.h.in new file mode 100644 index 00000000..44389679 --- /dev/null +++ b/StaticConfig.h.in @@ -0,0 +1,4 @@ +#cmakedefine DRIVER_LOG_FILE "@DRIVER_LOG_FILE@" +#cmakedefine APP_MANIFEST_PATH "@APP_MANIFEST_PATH@" +#cmakedefine DRIVER_MANIFEST_PATH "@DRIVER_MANIFEST_PATH@" +#cmakedefine DRIVER_INSTALLER_PATH "@DRIVER_INSTALLER_PATH@" diff --git a/driverInstall.py b/driverInstall.py new file mode 100755 index 00000000..08fb965d --- /dev/null +++ b/driverInstall.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 +import os, sys +import subprocess +import re +import argparse + +#vrpathreg = "/home/zack/.local/share/Steam/steamapps/common/SteamVR/bin/vrpathreg.sh" + +def GetDrivers(vrpathreg): + proc = subprocess.Popen([vrpathreg], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding='utf-8') + (stdout, _) = proc.communicate() + + lineno = 0 + externalReg = re.compile('.*External Drivers:.*') + lines = stdout.split('\n') + for line in lines: + lineno += 1 + if externalReg.match(line): + break + + lines = [ x.strip().split(':')[1].strip() for x in lines[lineno:] if len(x) > 0] + return lines + +def RemoveDriver(vrpathreg, driver): + cmd = [vrpathreg, 'removedriver', driver] + print(cmd) + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding='utf-8') + (stdout, _) = proc.communicate() + +def AddDriver(vrpathreg, driver): + cmd = [vrpathreg, 'adddriver', driver] + print(cmd) + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding='utf-8') + (stdout, _) = proc.communicate() + +def main(): + parser = argparse.ArgumentParser() + + parser.add_argument('--toInstall', help="Driver to install (folder path)", required=True) + parser.add_argument('--vrpathreg', help="Path to vrpathreg.sh", required=True) + + args = parser.parse_args() + + fail = False + if not os.path.exists(args.toInstall): + print("Driver path [{args.toInstall}] does not exist") + fail = True + + if not os.path.exists(args.vrpathreg): + print("Path to vrpathreg.sh [{args.toInstall}] does not exist") + fail = True + + if fail: + return + + drivers = GetDrivers(args.vrpathreg) + + spaceCalReg = re.compile('.*01spacecalibrator.*') + + for driver in drivers: + RemoveDriver(args.vrpathreg, driver) + + AddDriver(args.vrpathreg, args.toInstall) + + for driver in drivers[::-1]: + if spaceCalReg.match(driver): + continue + + AddDriver(args.vrpathreg, driver) + + pass + + +if __name__ == "__main__": + main() + diff --git a/modules/gl3w b/modules/gl3w deleted file mode 160000 index 5f8d7fd1..00000000 --- a/modules/gl3w +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5f8d7fd191ba22ff2b60c1106d7135bb9a335533 diff --git a/modules/openvr b/modules/openvr new file mode 160000 index 00000000..08de3821 --- /dev/null +++ b/modules/openvr @@ -0,0 +1 @@ +Subproject commit 08de3821dfd3aa46f778376680c68f33b9fdcb6c From e66339e476ad2f9232aeba03b6c96607ec308226 Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Sun, 4 Sep 2022 17:39:05 -0500 Subject: [PATCH 11/27] Fixing reversed mouse in Linux VR --- OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp | 14 +++++++++----- OpenVR-SpaceCalibrator/UserInterface.cpp | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp index ff581fb6..528a9de9 100644 --- a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp +++ b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp @@ -288,7 +288,11 @@ void RunLoop() switch (vrEvent.eventType) { case vr::VREvent_MouseMove: io.MousePos.x = vrEvent.data.mouse.x; +#ifdef __linux__ + io.MousePos.y = height - vrEvent.data.mouse.y; +#else io.MousePos.y = vrEvent.data.mouse.y; +#endif break; case vr::VREvent_MouseButtonDown: io.MouseDown[vrEvent.data.mouse.button == vr::VRMouseButton_Left ? 0 : 1] = true; @@ -449,17 +453,17 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance } #ifdef __linux__ bool StringMatch(wchar_t const * first, wchar_t const * second) { -#else -bool StringMatch(LPWSTR first, LPWSTR second) { -#endif bool ret; -#ifdef __linux__ ret = wcscmp(first, second) == 0; + return ret; +} #else +bool StringMatch(LPWSTR first, LPWSTR second) { + bool ret; ret = lstrcmp(first, second) == 0; -#endif return ret; } +#endif #ifdef __linux__ static void HandleCommandLine(wchar_t const * lpCmdLine) diff --git a/OpenVR-SpaceCalibrator/UserInterface.cpp b/OpenVR-SpaceCalibrator/UserInterface.cpp index db9b3ddd..d4d01d14 100644 --- a/OpenVR-SpaceCalibrator/UserInterface.cpp +++ b/OpenVR-SpaceCalibrator/UserInterface.cpp @@ -190,7 +190,7 @@ void BuildMenu(bool runningInOverlay) switch (message.type) { case CalibrationContext::Message::String: - ImGui::TextWrapped(message.str.c_str()); + ImGui::TextWrapped("%s", message.str.c_str()); break; case CalibrationContext::Message::Progress: float fraction = (float)message.progress / (float)message.target; From 2360f80a12e62fbe5ed2aa5b6a632c23d8009af8 Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Sun, 4 Sep 2022 20:00:36 -0500 Subject: [PATCH 12/27] Allow for better handling of dropped UDP packets fixes issue locking up on start up in some cases --- OpenVR-SpaceCalibrator/IPCClient.cpp | 22 ++++++++++--- OpenVR-SpaceCalibratorDriver/Comms.h | 47 ++++++++++++++++------------ 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/OpenVR-SpaceCalibrator/IPCClient.cpp b/OpenVR-SpaceCalibrator/IPCClient.cpp index 0f824b6e..dc76d694 100644 --- a/OpenVR-SpaceCalibrator/IPCClient.cpp +++ b/OpenVR-SpaceCalibrator/IPCClient.cpp @@ -66,8 +66,20 @@ void IPCClient::Connect() protocol::Response IPCClient::SendBlocking(const protocol::Request &request) { - Send(request); - return Receive(); +#ifdef __linux__ + for(int i=0; i<10; i++){ + Send(request); + try{ + return Receive(); + } catch (std::runtime_error &t) { + LOG("%s: %s", "Recv timeout failed", t.what()); + } + } + throw std::runtime_error("Fell through read loop"); +#else + Send(request); + return Receive(); +#endif } void IPCClient::Send(const protocol::Request &request) @@ -88,8 +100,10 @@ protocol::Response IPCClient::Receive() { protocol::Response response(protocol::ResponseInvalid); #ifdef __linux__ - pipe.Recv(&response); - return response; + if( pipe.Recv(&response) ) + return response; + else + throw std::runtime_error("No packet was received"); #else DWORD bytesRead; diff --git a/OpenVR-SpaceCalibratorDriver/Comms.h b/OpenVR-SpaceCalibratorDriver/Comms.h index 2ead52c3..17c5ac28 100644 --- a/OpenVR-SpaceCalibratorDriver/Comms.h +++ b/OpenVR-SpaceCalibratorDriver/Comms.h @@ -23,7 +23,7 @@ class UDPServerSocket{ UDPServerSocket(){} - bool Open(unsigned short port){ + bool Open(unsigned short port, int timeout=0){ sockaddr_in my_addr = {}; my_addr.sin_family = AF_INET; @@ -32,11 +32,20 @@ class UDPServerSocket{ //TODO verify that 0 is valid for UDP. sock = socket(AF_INET, SOCK_DGRAM, 0); + if(sock == -1){ LOG("Failed to create socket: %s", strerror(errno)); return false; } + + if(timeout > 0){ + struct timeval tv; + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof(tv)); + } + int err = bind(sock, (sockaddr*)&my_addr, sizeof(my_addr)); if(err){ LOG("Failed to bind socket: %s", strerror(errno)); @@ -84,12 +93,11 @@ class Comms{ } void Recv(RecvObj* obj){ - while(true){ - if(sock.Recv(obj, (sockaddr*) &lastClient, &peer_addr_len)){ - return; - } else { - LOG("%s", "failed to recve value"); - } + if(sock.Recv(obj, (sockaddr*) &lastClient, &peer_addr_len)){ + return; + } else { + LOG("%s", "failed to recve value"); + return; } } @@ -110,7 +118,7 @@ class Client{ Client& operator=(const Client& other) = delete; Client(){ - if( !sock.Open(COMM_PORT_CLIENT) ){ + if( !sock.Open(COMM_PORT_CLIENT, 1000) ){ LOG("%s", "Error opening server socket"); } @@ -119,18 +127,17 @@ class Client{ serverAddr.sin_addr.s_addr = INADDR_ANY; } - void Recv(RecvObj* obj){ - while(true){ - sockaddr_in lastClient; - lastClient.sin_family = AF_INET; - lastClient.sin_port = htons(COMM_PORT_SERVER); - lastClient.sin_addr.s_addr = INADDR_ANY; - - if(sock.Recv(obj, (sockaddr*) &lastClient, &peer_addr_len)){ - return; - } else { - LOG("%s", "failed to recve value"); - } + bool Recv(RecvObj* obj){ + sockaddr_in lastClient; + lastClient.sin_family = AF_INET; + lastClient.sin_port = htons(COMM_PORT_SERVER); + lastClient.sin_addr.s_addr = INADDR_ANY; + + if(sock.Recv(obj, (sockaddr*) &lastClient, &peer_addr_len)){ + return true; + } else { + LOG("%s", "failed to recve value"); + return false; } } From 5d34f8468fe4cbfc1161fdd1accfc62243336d52 Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Sun, 4 Sep 2022 20:39:33 -0500 Subject: [PATCH 13/27] Reducing windows delta --- OpenVR-SpaceCalibrator/UserInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenVR-SpaceCalibrator/UserInterface.cpp b/OpenVR-SpaceCalibrator/UserInterface.cpp index d4d01d14..94122f91 100644 --- a/OpenVR-SpaceCalibrator/UserInterface.cpp +++ b/OpenVR-SpaceCalibrator/UserInterface.cpp @@ -8,7 +8,7 @@ #include #include #include -#include "../lib/imgui/imgui.h" +#include "imgui/imgui.h" struct VRDevice { From 5adc5f2f46a9743295ae11163eb0c875ed842a78 Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Sun, 4 Sep 2022 20:40:10 -0500 Subject: [PATCH 14/27] Moving linux config path to StaticConfig --- CMakeLists.txt | 1 + OpenVR-SpaceCalibrator/Configuration.cpp | 1 + OpenVR-SpaceCalibrator/Configuration.h | 3 ++- StaticConfig.h.in | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d0b9c82..194beb93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ 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" ) add_library(imgui lib/imgui/imgui.cpp diff --git a/OpenVR-SpaceCalibrator/Configuration.cpp b/OpenVR-SpaceCalibrator/Configuration.cpp index 17470a5d..17c0eb88 100644 --- a/OpenVR-SpaceCalibrator/Configuration.cpp +++ b/OpenVR-SpaceCalibrator/Configuration.cpp @@ -201,6 +201,7 @@ static std::string ReadRegistryKey() static void WriteRegistryKey(std::string str) { #ifdef __linux__ + system("mkdir -p " LINUX_CONFIG_DIR); FILE* file = fopen(LINUX_CONFIG_FILE, "w"); if(!file) std::cerr << "Error opening config file for writing"; diff --git a/OpenVR-SpaceCalibrator/Configuration.h b/OpenVR-SpaceCalibrator/Configuration.h index cee7d17f..a3a56b35 100644 --- a/OpenVR-SpaceCalibrator/Configuration.h +++ b/OpenVR-SpaceCalibrator/Configuration.h @@ -1,8 +1,9 @@ #pragma once #include "Calibration.h" +#include "StaticConfig.h" -#define LINUX_CONFIG_FILE "/tmp/spacecal-config" +#define LINUX_CONFIG_FILE LINUX_CONFIG_DIR "spacecal-config" void LoadProfile(CalibrationContext &ctx); void SaveProfile(CalibrationContext &ctx); diff --git a/StaticConfig.h.in b/StaticConfig.h.in index 44389679..40b27bb5 100644 --- a/StaticConfig.h.in +++ b/StaticConfig.h.in @@ -2,3 +2,4 @@ #cmakedefine APP_MANIFEST_PATH "@APP_MANIFEST_PATH@" #cmakedefine DRIVER_MANIFEST_PATH "@DRIVER_MANIFEST_PATH@" #cmakedefine DRIVER_INSTALLER_PATH "@DRIVER_INSTALLER_PATH@" +#cmakedefine LINUX_CONFIG_DIR "@LINUX_CONFIG_DIR@" From 2debe7d094ffbab92786f5ab3790c9ffc5711006 Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Mon, 5 Sep 2022 13:11:57 -0500 Subject: [PATCH 15/27] Windows compatibility fix --- OpenVR-SpaceCalibrator/Configuration.h | 3 +++ OpenVR-SpaceCalibrator/IPCClient.cpp | 2 ++ OpenVR-SpaceCalibratorDriver/Logging.cpp | 6 ++++++ 3 files changed, 11 insertions(+) diff --git a/OpenVR-SpaceCalibrator/Configuration.h b/OpenVR-SpaceCalibrator/Configuration.h index a3a56b35..928cc30a 100644 --- a/OpenVR-SpaceCalibrator/Configuration.h +++ b/OpenVR-SpaceCalibrator/Configuration.h @@ -1,7 +1,10 @@ #pragma once #include "Calibration.h" + +#ifdef __linux__ #include "StaticConfig.h" +#endif #define LINUX_CONFIG_FILE LINUX_CONFIG_DIR "spacecal-config" diff --git a/OpenVR-SpaceCalibrator/IPCClient.cpp b/OpenVR-SpaceCalibrator/IPCClient.cpp index dc76d694..073dc087 100644 --- a/OpenVR-SpaceCalibrator/IPCClient.cpp +++ b/OpenVR-SpaceCalibrator/IPCClient.cpp @@ -1,6 +1,8 @@ #include "stdafx.h" #include "IPCClient.h" +#ifdef __linux__ #include "Comms.h" +#endif #include diff --git a/OpenVR-SpaceCalibratorDriver/Logging.cpp b/OpenVR-SpaceCalibratorDriver/Logging.cpp index c599ec44..e336498a 100644 --- a/OpenVR-SpaceCalibratorDriver/Logging.cpp +++ b/OpenVR-SpaceCalibratorDriver/Logging.cpp @@ -29,9 +29,15 @@ tm TimeForLog() auto now = std::chrono::system_clock::now(); auto nowTime = std::chrono::system_clock::to_time_t(now); +#ifdef __linux__ tm buf; auto tm = localtime_r(&nowTime, &buf); return *tm; +#else + tm value; + auto tm = localtime_s(&value, &nowTime); + return value; +#endif } From d69aac3e3062ddd67aefad0b6639c5fea8a589a2 Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Mon, 5 Sep 2022 13:20:57 -0500 Subject: [PATCH 16/27] better readme to include Linux build instructions --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 5b4b1f3f..f9746f7c 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,22 @@ You can calibrate without using the dashboard overlay by unminimizing Space Cali Open `OpenVR-SpaceCalibrator.sln` in Visual Studio 2017 and build. There are no external dependencies. +### Compiling on linux +Dependencies: eigen, openvr, python3, libgl + +Run the following from the main repo directory. + +``` +mkdir build +cd build +cmake .. +make +make install +``` + +The build prefix can be modified so that it points to an interanl directory for testing without installing. + + ### The math See [math.pdf](https://github.com/pushrax/OpenVR-SpaceCalibrator/blob/master/math.pdf) for details. From de98a3a5c9ec8aa3011f4e71b2d0960fd67130a0 Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Mon, 5 Sep 2022 15:34:16 -0500 Subject: [PATCH 17/27] Linux config file fixes --- CMakeLists.txt | 2 +- OpenVR-SpaceCalibrator/Configuration.cpp | 49 ++++++++++++++++++++++-- OpenVR-SpaceCalibrator/Configuration.h | 2 - OpenVR-SpaceCalibratorDriver/Logging.cpp | 2 +- 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 194beb93..bdf62661 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ 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" ) +set(LINUX_CONFIG_DIR, ".config/OpenVR-SpaceCalibrator" ) add_library(imgui lib/imgui/imgui.cpp diff --git a/OpenVR-SpaceCalibrator/Configuration.cpp b/OpenVR-SpaceCalibrator/Configuration.cpp index 17c0eb88..c0c42fd2 100644 --- a/OpenVR-SpaceCalibrator/Configuration.cpp +++ b/OpenVR-SpaceCalibrator/Configuration.cpp @@ -9,6 +9,15 @@ #include #include +#include "Logging.h" + +#ifdef __linux__ +#include +#include +#include +#define LINUX_CONFIG_FILE "spacecal-config.json" +#endif + static picojson::array FloatArray(const float *buf, int numFloats) { picojson::array arr; @@ -201,12 +210,44 @@ static std::string ReadRegistryKey() static void WriteRegistryKey(std::string str) { #ifdef __linux__ - system("mkdir -p " LINUX_CONFIG_DIR); - FILE* file = fopen(LINUX_CONFIG_FILE, "w"); - if(!file) std::cerr << "Error opening config file for writing"; + 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; + } + } + } - fprintf(file, "%s", str.c_str()); + 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; diff --git a/OpenVR-SpaceCalibrator/Configuration.h b/OpenVR-SpaceCalibrator/Configuration.h index 928cc30a..545bfba8 100644 --- a/OpenVR-SpaceCalibrator/Configuration.h +++ b/OpenVR-SpaceCalibrator/Configuration.h @@ -6,7 +6,5 @@ #include "StaticConfig.h" #endif -#define LINUX_CONFIG_FILE LINUX_CONFIG_DIR "spacecal-config" - void LoadProfile(CalibrationContext &ctx); void SaveProfile(CalibrationContext &ctx); diff --git a/OpenVR-SpaceCalibratorDriver/Logging.cpp b/OpenVR-SpaceCalibratorDriver/Logging.cpp index e336498a..5a6d7f51 100644 --- a/OpenVR-SpaceCalibratorDriver/Logging.cpp +++ b/OpenVR-SpaceCalibratorDriver/Logging.cpp @@ -14,7 +14,7 @@ FILE *LogFile; void OpenLogFile() { - LogFile = fopen(DRIVER_LOG_FILE, "w"); + LogFile = fopen(DRIVER_LOG_FILE, "a"); if (LogFile == nullptr) { LogFile = stderr; From 87d174bc148ba3cea2b8c543e942cd1ab4cc25d6 Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Mon, 5 Sep 2022 17:30:32 -0500 Subject: [PATCH 18/27] Fixing up some fresh build issues. --- CMakeLists.txt | 2 +- OpenVR-SpaceCalibrator/Configuration.cpp | 1 + README.md | 9 ++++++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bdf62661..6fa01f6a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ 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" ) +set(LINUX_CONFIG_DIR ".config/OpenVR-SpaceCalibrator" CACHE PATH "Config subdirectory (from HOME)" ) add_library(imgui lib/imgui/imgui.cpp diff --git a/OpenVR-SpaceCalibrator/Configuration.cpp b/OpenVR-SpaceCalibrator/Configuration.cpp index c0c42fd2..80613069 100644 --- a/OpenVR-SpaceCalibrator/Configuration.cpp +++ b/OpenVR-SpaceCalibrator/Configuration.cpp @@ -15,6 +15,7 @@ #include #include #include +#include "StaticConfig.h" #define LINUX_CONFIG_FILE "spacecal-config.json" #endif diff --git a/README.md b/README.md index f9746f7c..3557b3a5 100644 --- a/README.md +++ b/README.md @@ -42,14 +42,16 @@ As part of first time setup, or when you make a change to your space (e.g. move You can calibrate without using the dashboard overlay by unminimizing Space Calibrator after opening SteamVR (it starts minimized). This is required if you're calibrating for a lone HMD without any devices in its tracking system. -### Compiling your own build +### Compiling your own Windows build Open `OpenVR-SpaceCalibrator.sln` in Visual Studio 2017 and build. There are no external dependencies. -### Compiling on linux +### Compiling on Linux Dependencies: eigen, openvr, python3, libgl -Run the following from the main repo directory. +Further dependencies will be downloaded as git submodules as part of the build process. + +Run the following from the main repo directory to build and install. ``` mkdir build @@ -62,6 +64,7 @@ make install The build prefix can be modified so that it points to an interanl directory for testing without installing. + ### The math See [math.pdf](https://github.com/pushrax/OpenVR-SpaceCalibrator/blob/master/math.pdf) for details. From 723c10ac7874f5ab2a30aad4d0e1d49db55976f9 Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Tue, 27 Sep 2022 18:51:54 -0500 Subject: [PATCH 19/27] Fixing config finding bug --- OpenVR-SpaceCalibrator/Configuration.cpp | 40 +++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/OpenVR-SpaceCalibrator/Configuration.cpp b/OpenVR-SpaceCalibrator/Configuration.cpp index 80613069..e99d6200 100644 --- a/OpenVR-SpaceCalibrator/Configuration.cpp +++ b/OpenVR-SpaceCalibrator/Configuration.cpp @@ -167,7 +167,45 @@ static void LogRegistryResult(LSTATUS result) static std::string ReadRegistryKey() { #ifdef __linux__ - FILE* file = fopen(LINUX_CONFIG_FILE, "r"); + + 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; From d70cb845fb8294a0ea31cbcfa444c9a6fca2d987 Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Sun, 16 Oct 2022 23:05:48 -0500 Subject: [PATCH 20/27] First steps on resolving change requests --- CMakeLists.txt | 7 +- OpenVR-SpaceCalibrator/Configuration.cpp | 121 +---- .../Configuration_linux.cpp | 282 ++++++++++ OpenVR-SpaceCalibrator/HandleCommandLine.h | 119 +++++ .../HandleCommandLine_linux.cpp | 7 + .../HandleCommandLine_win.cpp | 5 + .../OpenVR-SpaceCalibrator.cpp | 265 +--------- .../OpenVR-SpaceCalibrator_linux.cpp | 492 ++++++++++++++++++ OpenVR-SpaceCalibratorDriver/compat.cpp | 43 -- OpenVR-SpaceCalibratorDriver/compat.h | 44 -- Version.h | 4 - 11 files changed, 929 insertions(+), 460 deletions(-) create mode 100644 OpenVR-SpaceCalibrator/Configuration_linux.cpp create mode 100644 OpenVR-SpaceCalibrator/HandleCommandLine.h create mode 100644 OpenVR-SpaceCalibrator/HandleCommandLine_linux.cpp create mode 100644 OpenVR-SpaceCalibrator/HandleCommandLine_win.cpp create mode 100644 OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator_linux.cpp delete mode 100644 OpenVR-SpaceCalibratorDriver/compat.cpp delete mode 100644 OpenVR-SpaceCalibratorDriver/compat.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6fa01f6a..adac6470 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ 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(DRIVER_LOG_FILE "/tmp/space_calibrator_driver.log" CACHE PATH "Driver Log Path" ) set(LINUX_CONFIG_DIR ".config/OpenVR-SpaceCalibrator" CACHE PATH "Config subdirectory (from HOME)" ) add_library(imgui @@ -34,9 +34,10 @@ set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED True) add_executable(OpenVR-SpaceCalibrator - OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp + OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator_linux.cpp OpenVR-SpaceCalibrator/Calibration.cpp - OpenVR-SpaceCalibrator/Configuration.cpp + OpenVR-SpaceCalibrator/Configuration_linux.cpp + OpenVR-SpaceCalibrator/HandleCommandLine_linux.cpp OpenVR-SpaceCalibrator/EmbeddedFiles.cpp OpenVR-SpaceCalibrator/IPCClient.cpp OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp diff --git a/OpenVR-SpaceCalibrator/Configuration.cpp b/OpenVR-SpaceCalibrator/Configuration.cpp index e99d6200..5dfc4911 100644 --- a/OpenVR-SpaceCalibrator/Configuration.cpp +++ b/OpenVR-SpaceCalibrator/Configuration.cpp @@ -4,21 +4,11 @@ #include #include -#include "stdio.h" +#include #include #include #include -#include "Logging.h" - -#ifdef __linux__ -#include -#include -#include -#include "StaticConfig.h" -#define LINUX_CONFIG_FILE "spacecal-config.json" -#endif - static picojson::array FloatArray(const float *buf, int numFloats) { picojson::array arr; @@ -35,7 +25,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(); - if (arr.size() != (size_t) numFloats) + if (arr.size() != numFloats) throw std::runtime_error("wrong buffer size"); for (int i = 0; i < numFloats; i++) @@ -152,77 +142,17 @@ static void WriteProfile(CalibrationContext &ctx, std::ostream &out) out << profilesV.serialize(true); } -#ifdef __linux__ -// 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; } -#endif + +static const char *RegistryKey = "Software\\OpenVR-SpaceCalibrator"; 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) @@ -243,52 +173,10 @@ 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) @@ -304,7 +192,6 @@ static void WriteRegistryKey(std::string str) LogRegistryResult(result); RegCloseKey(hkey); -#endif } void LoadProfile(CalibrationContext &ctx) diff --git a/OpenVR-SpaceCalibrator/Configuration_linux.cpp b/OpenVR-SpaceCalibrator/Configuration_linux.cpp new file mode 100644 index 00000000..c146c9ce --- /dev/null +++ b/OpenVR-SpaceCalibrator/Configuration_linux.cpp @@ -0,0 +1,282 @@ +#include "stdafx.h" +#include "Configuration.h" + +#include + +#include +#include "stdio.h" +#include +#include +#include + +#include "Logging.h" + +#ifdef __linux__ +#include +#include +#include +#include "StaticConfig.h" +#define LINUX_CONFIG_FILE "spacecal-config.json" +#endif + +static picojson::array FloatArray(const float *buf, int numFloats) +{ + picojson::array arr; + + for (int i = 0; i < numFloats; i++) + arr.push_back(picojson::value(double(buf[i]))); + + return arr; +} + +static void LoadFloatArray(const picojson::value &obj, float *buf, int numFloats) +{ + if (!obj.is()) + throw std::runtime_error("expected array, got " + obj.to_str()); + + auto &arr = obj.get(); + if (arr.size() != (size_t) numFloats) + throw std::runtime_error("wrong buffer size"); + + for (int i = 0; i < numFloats; i++) + buf[i] = (float) arr[i].get(); +} + +static void ParseProfile(CalibrationContext &ctx, std::istream &stream) +{ + picojson::value v; + std::string err = picojson::parse(v, stream); + if (!err.empty()) + throw std::runtime_error(err); + + auto arr = v.get(); + if (arr.size() < 1) + throw std::runtime_error("no profiles in file"); + + auto obj = arr[0].get(); + + ctx.referenceTrackingSystem = obj["reference_tracking_system"].get(); + ctx.targetTrackingSystem = obj["target_tracking_system"].get(); + ctx.calibratedRotation(0) = obj["roll"].get(); + ctx.calibratedRotation(1) = obj["yaw"].get(); + ctx.calibratedRotation(2) = obj["pitch"].get(); + ctx.calibratedTranslation(0) = obj["x"].get(); + ctx.calibratedTranslation(1) = obj["y"].get(); + ctx.calibratedTranslation(2) = obj["z"].get(); + + if (obj["scale"].is()) + ctx.calibratedScale = obj["scale"].get(); + else + ctx.calibratedScale = 1.0; + + if (obj["calibration_speed"].is()) + ctx.calibrationSpeed = (CalibrationContext::Speed)(int) obj["calibration_speed"].get(); + + if (obj["chaperone"].is()) + { + auto chaperone = obj["chaperone"].get(); + ctx.chaperone.autoApply = chaperone["auto_apply"].get(); + + LoadFloatArray(chaperone["play_space_size"], ctx.chaperone.playSpaceSize.v, 2); + + LoadFloatArray( + chaperone["standing_center"], + (float *) ctx.chaperone.standingCenter.m, + sizeof(ctx.chaperone.standingCenter.m) / sizeof(float) + ); + + if (!chaperone["geometry"].is()) + throw std::runtime_error("chaperone geometry is not an array"); + + auto &geometry = chaperone["geometry"].get(); + + if (geometry.size() > 0) + { + ctx.chaperone.geometry.resize(geometry.size() * sizeof(float) / sizeof(ctx.chaperone.geometry[0])); + LoadFloatArray(chaperone["geometry"], (float *) ctx.chaperone.geometry.data(), geometry.size()); + + ctx.chaperone.valid = true; + } + } + + ctx.validProfile = true; +} + +static void WriteProfile(CalibrationContext &ctx, std::ostream &out) +{ + if (!ctx.validProfile) + return; + + picojson::object profile; + profile["reference_tracking_system"].set(ctx.referenceTrackingSystem); + profile["target_tracking_system"].set(ctx.targetTrackingSystem); + profile["roll"].set(ctx.calibratedRotation(0)); + profile["yaw"].set(ctx.calibratedRotation(1)); + profile["pitch"].set(ctx.calibratedRotation(2)); + profile["x"].set(ctx.calibratedTranslation(0)); + profile["y"].set(ctx.calibratedTranslation(1)); + profile["z"].set(ctx.calibratedTranslation(2)); + profile["scale"].set(ctx.calibratedScale); + + double speed = (int) ctx.calibrationSpeed; + profile["calibration_speed"].set(speed); + + if (ctx.chaperone.valid) + { + picojson::object chaperone; + chaperone["auto_apply"].set(ctx.chaperone.autoApply); + chaperone["play_space_size"].set(FloatArray(ctx.chaperone.playSpaceSize.v, 2)); + + chaperone["standing_center"].set(FloatArray( + (float *) ctx.chaperone.standingCenter.m, + sizeof(ctx.chaperone.standingCenter.m) / sizeof(float) + )); + + chaperone["geometry"].set(FloatArray( + (float *) ctx.chaperone.geometry.data(), + sizeof(ctx.chaperone.geometry[0]) / sizeof(float) * ctx.chaperone.geometry.size() + )); + + profile["chaperone"].set(chaperone); + } + + picojson::value profileV; + profileV.set(profile); + + picojson::array profiles; + profiles.push_back(profileV); + + picojson::value profilesV; + profilesV.set(profiles); + + out << profilesV.serialize(true); +} + +static std::string ReadRegistryKey() +{ + 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; +} + +static void WriteRegistryKey(std::string str) +{ + 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); +} + +void LoadProfile(CalibrationContext &ctx) +{ + ctx.validProfile = false; + + auto str = ReadRegistryKey(); + if (str == "") + { + std::cout << "Profile is empty" << std::endl; + ctx.Clear(); + return; + } + + try + { + std::stringstream io(str); + ParseProfile(ctx, io); + std::cout << "Loaded profile" << std::endl; + } + catch (const std::runtime_error &e) + { + std::cerr << "Error loading profile: " << e.what() << std::endl; + } +} + +void SaveProfile(CalibrationContext &ctx) +{ + std::cout << "Saving profile to registry" << std::endl; + + std::stringstream io; + WriteProfile(ctx, io); + WriteRegistryKey(io.str()); +} + diff --git a/OpenVR-SpaceCalibrator/HandleCommandLine.h b/OpenVR-SpaceCalibrator/HandleCommandLine.h new file mode 100644 index 00000000..d23b0ad4 --- /dev/null +++ b/OpenVR-SpaceCalibrator/HandleCommandLine.h @@ -0,0 +1,119 @@ +#include +#define OPENVR_APPLICATION_KEY "pushrax.SpaceCalibrator" +#include +#include +#include + + +namespace HandleCommandLine { + +std::string ManifestPath(std::string cwd); + +static inline void OpenVRPath(char * cruntimePath, int cruntimePathLength){ + auto vrErr = vr::VRInitError_None; + vr::VR_Init(&vrErr, vr::VRApplication_Utility); + if (vrErr == vr::VRInitError_None) + { + unsigned int pathLen; + vr::VR_GetRuntimePath(cruntimePath, cruntimePathLength, &pathLen); + + printf("%s", cruntimePath); + vr::VR_Shutdown(); + exit(0); + } + fprintf(stderr, "Failed to initialize OpenVR: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(vrErr)); + vr::VR_Shutdown(); + exit(-2); +} + +static inline void InstallManifest(char const * const cwd, int max_path) { + auto vrErr = vr::VRInitError_None; + vr::VR_Init(&vrErr, vr::VRApplication_Utility); + if (vrErr == vr::VRInitError_None) + { + if (vr::VRApplications()->IsApplicationInstalled(OPENVR_APPLICATION_KEY)) + { + auto oldWd = std::make_unique(max_path); + memset((void*)oldWd.get(), 0, max_path); + + auto vrAppErr = vr::VRApplicationError_None; + vr::VRApplications()->GetApplicationPropertyString(OPENVR_APPLICATION_KEY, vr::VRApplicationProperty_WorkingDirectory_String, oldWd.get(), max_path, &vrAppErr); + if (vrAppErr != vr::VRApplicationError_None) + { + fprintf(stderr, "Failed to get old working dir, skipping removal: %s\n", vr::VRApplications()->GetApplicationsErrorNameFromEnum(vrAppErr)); + } + else + { + std::string manifestPath = oldWd.get(); + manifestPath = HandleCommandLine::ManifestPath(manifestPath); + std::cout << "Removing old manifest path: " << manifestPath << std::endl; + vr::VRApplications()->RemoveApplicationManifest(manifestPath.c_str()); + } + } + std::string manifestPath = cwd; + manifestPath = HandleCommandLine::ManifestPath(manifestPath); + + std::cout << "Adding manifest path: " << manifestPath << std::endl; + auto vrAppErr = vr::VRApplications()->AddApplicationManifest(manifestPath.c_str()); + if (vrAppErr != vr::VRApplicationError_None) + { + fprintf(stderr, "Failed to add manifest: %s\n", vr::VRApplications()->GetApplicationsErrorNameFromEnum(vrAppErr)); + } + else + { + vr::VRApplications()->SetApplicationAutoLaunch(OPENVR_APPLICATION_KEY, true); + } + vr::VR_Shutdown(); + exit(-2); + } + fprintf(stderr, "Failed to initialize OpenVR: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(vrErr)); + vr::VR_Shutdown(); + exit(-2); +} + +static inline void RemoveManifest(char const * const cwd) { + auto vrErr = vr::VRInitError_None; + vr::VR_Init(&vrErr, vr::VRApplication_Utility); + if (vrErr == vr::VRInitError_None) + { + if (vr::VRApplications()->IsApplicationInstalled(OPENVR_APPLICATION_KEY)) + { + std::string manifestPath = cwd; + manifestPath = ManifestPath(manifestPath); + + std::cout << "Removing manifest path: " << manifestPath << std::endl; + vr::VRApplications()->RemoveApplicationManifest(manifestPath.c_str()); + } + vr::VR_Shutdown(); + exit(0); + } + fprintf(stderr, "Failed to initialize OpenVR: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(vrErr)); + vr::VR_Shutdown(); + exit(-2); +} + +static inline void ActivateMultipleDrivers() { + int ret = -2; + auto vrErr = vr::VRInitError_None; + vr::VR_Init(&vrErr, vr::VRApplication_Utility); + if (vrErr == vr::VRInitError_None) + { + try + { + ActivateMultipleDrivers(); + ret = 0; + } + catch (std::runtime_error &e) + { + std::cerr << e.what() << std::endl; + } + } + else + { + fprintf(stderr, "Failed to initialize OpenVR: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(vrErr)); + } + vr::VR_Shutdown(); + exit(ret); +} + +} // namespace HandleCommandLine diff --git a/OpenVR-SpaceCalibrator/HandleCommandLine_linux.cpp b/OpenVR-SpaceCalibrator/HandleCommandLine_linux.cpp new file mode 100644 index 00000000..b7d00b39 --- /dev/null +++ b/OpenVR-SpaceCalibrator/HandleCommandLine_linux.cpp @@ -0,0 +1,7 @@ +#include "HandleCommandLine.h" + +#include "StaticConfig.h" +std::string HandleCommandLine::ManifestPath(std::string /* cwd */){ + return APP_MANIFEST_PATH; +} + diff --git a/OpenVR-SpaceCalibrator/HandleCommandLine_win.cpp b/OpenVR-SpaceCalibrator/HandleCommandLine_win.cpp new file mode 100644 index 00000000..85a246e4 --- /dev/null +++ b/OpenVR-SpaceCalibrator/HandleCommandLine_win.cpp @@ -0,0 +1,5 @@ +#include "HandleCommandLine.h" + +std::string HandleCommandLine::ManifestPath(std::string cwd){ + return cwd + "\\manifest.vrmanifest"; +} diff --git a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp index 528a9de9..5281860c 100644 --- a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp +++ b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp @@ -4,50 +4,24 @@ #include "EmbeddedFiles.h" #include "UserInterface.h" -#include -#include -#include -#include "GL/gl3w.h" - -#ifdef __linux__ -#include -#else -#include -#endif - #include #include #include - - +#include #include #include +#include +#include "HandleCommandLine.h" -#ifdef __linux__ -#include "StaticConfig.h" -#else #pragma comment(linker,"\"/manifestdependency:type='win32' \ name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") -#endif #define OPENVR_APPLICATION_KEY "pushrax.SpaceCalibrator" -#ifdef __linux__ -#else extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001; -#endif - -#ifdef __linux__ -#define MANIFEST_PATH(CWD) (APP_MANIFEST_PATH) -#else -#define MANIFEST_PATH(CWD) (CWD + "\\manifest.vrmanifest") -#endif - -//#define DEBUG_LOGS -#ifdef DEBUG_LOGS void CreateConsole() { static bool created = false; @@ -61,22 +35,20 @@ void CreateConsole() created = true; } } -#endif + +//#define DEBUG_LOGS void GLFWErrorCallback(int error, const char* description) { fprintf(stderr, "GLFW Error %d: %s\n", error, description); } -void openGLDebugCallback(GLenum /* source */, GLenum /* type */, GLuint id, GLenum /* severity */, GLsizei length, const GLchar *message, const void * /* userParam */ ) +void openGLDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) { fprintf(stderr, "OpenGL Debug %u: %.*s\n", id, length, message); } -#ifdef __linux__ -static void HandleCommandLine(wchar_t const * lpCmdLine); -#else + static void HandleCommandLine(LPWSTR lpCmdLine); -#endif static GLFWwindow *glfwWindow = nullptr; static vr::VROverlayHandle_t overlayMainHandle = 0, overlayThumbnailHandle = 0; @@ -288,11 +260,7 @@ void RunLoop() switch (vrEvent.eventType) { case vr::VREvent_MouseMove: io.MousePos.x = vrEvent.data.mouse.x; -#ifdef __linux__ - io.MousePos.y = height - vrEvent.data.mouse.y; -#else io.MousePos.y = vrEvent.data.mouse.y; -#endif break; case vr::VREvent_MouseButtonDown: io.MouseDown[vrEvent.data.mouse.button == vr::VRMouseButton_Left ? 0 : 1] = true; @@ -372,38 +340,9 @@ void RunLoop() } } -using convert_t = std::codecvt_utf8; -std::wstring_convert strconverter; - -std::string to_string(std::wstring wstr) -{ - return strconverter.to_bytes(wstr); -} - -std::wstring to_wstring(std::string str) -{ - return strconverter.from_bytes(str); -} - -#ifdef __linux__ -int main(int argc, char ** argv) -{ - wchar_t const * lpCmdLine; - std::wstring wide; - for(int i=1; iIsApplicationInstalled(OPENVR_APPLICATION_KEY)) - { - char oldWd[MAX_PATH] = { 0 }; - auto vrAppErr = vr::VRApplicationError_None; - vr::VRApplications()->GetApplicationPropertyString(OPENVR_APPLICATION_KEY, vr::VRApplicationProperty_WorkingDirectory_String, oldWd, MAX_PATH, &vrAppErr); - if (vrAppErr != vr::VRApplicationError_None) - { - fprintf(stderr, "Failed to get old working dir, skipping removal: %s\n", vr::VRApplications()->GetApplicationsErrorNameFromEnum(vrAppErr)); - } - else - { - std::string manifestPath = oldWd; - manifestPath = MANIFEST_PATH(manifestPath); - std::cout << "Removing old manifest path: " << manifestPath << std::endl; - vr::VRApplications()->RemoveApplicationManifest(manifestPath.c_str()); - } - } - std::string manifestPath = cwd; - manifestPath = MANIFEST_PATH(manifestPath); - - std::cout << "Adding manifest path: " << manifestPath << std::endl; - auto vrAppErr = vr::VRApplications()->AddApplicationManifest(manifestPath.c_str()); - if (vrAppErr != vr::VRApplicationError_None) - { - fprintf(stderr, "Failed to add manifest: %s\n", vr::VRApplications()->GetApplicationsErrorNameFromEnum(vrAppErr)); - } - else - { - vr::VRApplications()->SetApplicationAutoLaunch(OPENVR_APPLICATION_KEY, true); - } - vr::VR_Shutdown(); - exit(-2); - } - fprintf(stderr, "Failed to initialize OpenVR: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(vrErr)); - vr::VR_Shutdown(); - exit(-2); - } - else if (StringMatch(lpCmdLine, L"-removemanifest")) - { - auto vrErr = vr::VRInitError_None; - vr::VR_Init(&vrErr, vr::VRApplication_Utility); - if (vrErr == vr::VRInitError_None) - { - if (vr::VRApplications()->IsApplicationInstalled(OPENVR_APPLICATION_KEY)) - { - std::string manifestPath = cwd; - manifestPath = MANIFEST_PATH(manifestPath); - - std::cout << "Removing manifest path: " << manifestPath << std::endl; - vr::VRApplications()->RemoveApplicationManifest(manifestPath.c_str()); - } - vr::VR_Shutdown(); - exit(0); - } - fprintf(stderr, "Failed to initialize OpenVR: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(vrErr)); - vr::VR_Shutdown(); - exit(-2); - } - else if (StringMatch(lpCmdLine, L"-activatemultipledrivers")) - { - int ret = -2; - auto vrErr = vr::VRInitError_None; - vr::VR_Init(&vrErr, vr::VRApplication_Utility); - if (vrErr == vr::VRInitError_None) - { - try - { - ActivateMultipleDrivers(); - ret = 0; - } - catch (std::runtime_error &e) - { - std::cerr << e.what() << std::endl; - } - } - else - { - fprintf(stderr, "Failed to initialize OpenVR: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(vrErr)); - } - vr::VR_Shutdown(); - exit(ret); + HandleCommandLine::InstallManifest(cwd, MAX_PATH); } -#ifdef __linux__ - else if (StringMatch(lpCmdLine, L"-installdriver")) + else if (lstrcmp(lpCmdLine, L"-removemanifest") == 0) { - auto vrErr = vr::VRInitError_None; - vr::VR_Init(&vrErr, vr::VRApplication_Utility); - if (vrErr != vr::VRInitError_None) - { - fprintf(stderr, "Failed to initialize OpenVR: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(vrErr)); - vr::VR_Shutdown(); - exit(-2); - } - - char cruntimePath[MAX_PATH] = { 0 }; - unsigned int pathLen; - vr::VR_GetRuntimePath(cruntimePath, MAX_PATH, &pathLen); - - const int cmdLength = 8196; - char cmd[cmdLength]; - - snprintf(cmd, cmdLength, "python " DRIVER_INSTALLER_PATH "/driverInstall.py --toInstall " DRIVER_MANIFEST_PATH " --vrpathreg %s/bin/vrpathreg.sh", cruntimePath); - printf("cmd: %s\n", cmd); - system(cmd); - - vr::VR_Shutdown(); - exit(0); + HandleCommandLine::RemoveManifest(cwd); } - else if (StringMatch(lpCmdLine, L"-uninstalldriver")) + else if (lstrcmp(lpCmdLine, L"-activatemultipledrivers") == 0) { - auto vrErr = vr::VRInitError_None; - vr::VR_Init(&vrErr, vr::VRApplication_Utility); - if (vrErr != vr::VRInitError_None) - { - fprintf(stderr, "Failed to initialize OpenVR: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(vrErr)); - vr::VR_Shutdown(); - exit(-2); - } - - char cruntimePath[MAX_PATH] = { 0 }; - unsigned int pathLen; - vr::VR_GetRuntimePath(cruntimePath, MAX_PATH, &pathLen); - - const int cmdLength = 8196; - char cmd[cmdLength]; - - snprintf(cmd, cmdLength, "\"%s/bin/vrpathreg.sh\" removedriverwithname 01spacecalibrator", cruntimePath); - printf("cmd: %s\n", cmd); - - vr::VR_Shutdown(); - exit(0); + HandleCommandLine::ActivateMultipleDrivers(); } -#endif - } diff --git a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator_linux.cpp b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator_linux.cpp new file mode 100644 index 00000000..75fac955 --- /dev/null +++ b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator_linux.cpp @@ -0,0 +1,492 @@ +#include "stdafx.h" +#include "Calibration.h" +#include "Configuration.h" +#include "EmbeddedFiles.h" +#include "UserInterface.h" + +#include +#include +#include +#include "GL/gl3w.h" + +#include + +#include "HandleCommandLine.h" + +#include +#include +#include + +#include +#include + +#include "StaticConfig.h" + +void GLFWErrorCallback(int error, const char* description) +{ + fprintf(stderr, "GLFW Error %d: %s\n", error, description); +} + +void openGLDebugCallback(GLenum /* source */, GLenum /* type */, GLuint id, GLenum /* severity */, GLsizei length, const GLchar *message, const void * /* userParam */ ) +{ + fprintf(stderr, "OpenGL Debug %u: %.*s\n", id, length, message); +} + +static GLFWwindow *glfwWindow = nullptr; +static vr::VROverlayHandle_t overlayMainHandle = 0, overlayThumbnailHandle = 0; +static GLuint fboHandle = 0, fboTextureHandle = 0; +static int fboTextureWidth = 0, fboTextureHeight = 0; + +void CreateGLFWWindow() +{ + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_RESIZABLE, false); + +#ifdef DEBUG_LOGS + glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); +#endif + + fboTextureWidth = 1200; + fboTextureHeight = 800; + + glfwWindow = glfwCreateWindow(fboTextureWidth, fboTextureHeight, "OpenVR-SpaceCalibrator", NULL, NULL); + if (!glfwWindow) + throw std::runtime_error("Failed to create window"); + + glfwMakeContextCurrent(glfwWindow); + glfwSwapInterval(1); + gl3wInit(); + + glfwIconifyWindow(glfwWindow); + +#ifdef DEBUG_LOGS + glDebugMessageCallback(openGLDebugCallback, nullptr); + glEnable(GL_DEBUG_OUTPUT); +#endif + + ImGui::CreateContext(); + ImGuiIO &io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; + io.IniFilename = nullptr; + io.Fonts->AddFontFromMemoryCompressedTTF(DroidSans_compressed_data, DroidSans_compressed_size, 24.0f); + + ImGui_ImplGlfw_InitForOpenGL(glfwWindow, true); + ImGui_ImplOpenGL3_Init("#version 330"); + + ImGui::StyleColorsDark(); + + glGenTextures(1, &fboTextureHandle); + glBindTexture(GL_TEXTURE_2D, fboTextureHandle); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, fboTextureWidth, fboTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glGenFramebuffers(1, &fboHandle); + glBindFramebuffer(GL_FRAMEBUFFER, fboHandle); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, fboTextureHandle, 0); + + GLenum drawBuffers[1] = { GL_COLOR_ATTACHMENT0 }; + glDrawBuffers(1, drawBuffers); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + { + throw std::runtime_error("OpenGL framebuffer incomplete"); + } +} + +void TryCreateVROverlay() +{ + if (overlayMainHandle || !vr::VROverlay()) + return; + + vr::VROverlayError error = vr::VROverlay()->CreateDashboardOverlay( + "pushrax.SpaceCalibrator", "Space Cal", + &overlayMainHandle, &overlayThumbnailHandle + ); + + if (error == vr::VROverlayError_KeyInUse) + { + throw std::runtime_error("Another instance of OpenVR Space Calibrator is already running"); + } + else if (error != vr::VROverlayError_None) + { + throw std::runtime_error("Error creating VR overlay: " + std::string(vr::VROverlay()->GetOverlayErrorNameFromEnum(error))); + } + + vr::VROverlay()->SetOverlayWidthInMeters(overlayMainHandle, 3.0f); + vr::VROverlay()->SetOverlayInputMethod(overlayMainHandle, vr::VROverlayInputMethod_Mouse); + vr::VROverlay()->SetOverlayFlag(overlayMainHandle, vr::VROverlayFlags_SendVRDiscreteScrollEvents, true); + + std::string iconPath = cwd; + iconPath += "\\icon.png"; + vr::VROverlay()->SetOverlayFromFile(overlayThumbnailHandle, iconPath.c_str()); +} + +void ActivateMultipleDrivers() +{ + vr::EVRSettingsError vrSettingsError; + bool enabled = vr::VRSettings()->GetBool(vr::k_pch_SteamVR_Section, vr::k_pch_SteamVR_ActivateMultipleDrivers_Bool, &vrSettingsError); + + if (vrSettingsError != vr::VRSettingsError_None) + { + std::string err = "Could not read \"" + std::string(vr::k_pch_SteamVR_ActivateMultipleDrivers_Bool) + "\" setting: " + + vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); + + throw std::runtime_error(err); + } + + if (!enabled) + { + vr::VRSettings()->SetBool(vr::k_pch_SteamVR_Section, vr::k_pch_SteamVR_ActivateMultipleDrivers_Bool, true, &vrSettingsError); + if (vrSettingsError != vr::VRSettingsError_None) + { + std::string err = "Could not set \"" + std::string(vr::k_pch_SteamVR_ActivateMultipleDrivers_Bool) + "\" setting: " + + vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); + + throw std::runtime_error(err); + } + + std::cerr << "Enabled \"" << vr::k_pch_SteamVR_ActivateMultipleDrivers_Bool << "\" setting" << std::endl; + } + else + { + std::cerr << "\"" << vr::k_pch_SteamVR_ActivateMultipleDrivers_Bool << "\" setting previously enabled" << std::endl; + } +} + +void InitVR() +{ + auto initError = vr::VRInitError_None; + vr::VR_Init(&initError, vr::VRApplication_Other); + if (initError != vr::VRInitError_None) + { + auto error = vr::VR_GetVRInitErrorAsEnglishDescription(initError); + throw std::runtime_error("OpenVR error:" + std::string(error)); + } + + if (!vr::VR_IsInterfaceVersionValid(vr::IVRSystem_Version)) + { + throw std::runtime_error("OpenVR error: Outdated IVRSystem_Version"); + } + else if (!vr::VR_IsInterfaceVersionValid(vr::IVRSettings_Version)) + { + throw std::runtime_error("OpenVR error: Outdated IVRSettings_Version"); + } + else if (!vr::VR_IsInterfaceVersionValid(vr::IVROverlay_Version)) + { + throw std::runtime_error("OpenVR error: Outdated IVROverlay_Version"); + } + + ActivateMultipleDrivers(); +} + +void RunLoop() +{ + while (!glfwWindowShouldClose(glfwWindow)) + { + TryCreateVROverlay(); + + double time = glfwGetTime(); + CalibrationTick(time); + + bool dashboardVisible = false; + int width, height; + glfwGetFramebufferSize(glfwWindow, &width, &height); + + if (overlayMainHandle && vr::VROverlay()) + { + auto &io = ImGui::GetIO(); + dashboardVisible = vr::VROverlay()->IsActiveDashboardOverlay(overlayMainHandle); + + static bool keyboardOpen = false, keyboardJustClosed = false; + + // After closing the keyboard, this code waits one frame for ImGui to pick up the new text from SetActiveText + // before clearing the active widget. Then it waits another frame before allowing the keyboard to open again, + // otherwise it will do so instantly since WantTextInput is still true on the second frame. + if (keyboardJustClosed && keyboardOpen) + { + ImGui::ClearActiveID(); + keyboardOpen = false; + } + else if (keyboardJustClosed) + { + keyboardJustClosed = false; + } + else if (!io.WantTextInput) + { + // User might close the keyboard without hitting Done, so we unset the flag to allow it to open again. + keyboardOpen = false; + } + else if (io.WantTextInput && !keyboardOpen && !keyboardJustClosed) + { + char buf[0x400]; + ImGui::GetActiveText(buf, sizeof buf); + buf[0x3ff] = 0; + uint32_t unFlags = 0; // EKeyboardFlags + + vr::VROverlay()->ShowKeyboardForOverlay( + overlayMainHandle, vr::k_EGamepadTextInputModeNormal, vr::k_EGamepadTextInputLineModeSingleLine, + unFlags, "Space Calibrator Overlay", sizeof buf, buf, 0 + ); + keyboardOpen = true; + } + + vr::VREvent_t vrEvent; + while (vr::VROverlay()->PollNextOverlayEvent(overlayMainHandle, &vrEvent, sizeof(vrEvent))) + { + switch (vrEvent.eventType) { + case vr::VREvent_MouseMove: + io.MousePos.x = vrEvent.data.mouse.x; + //The mouse is flipped in linux + io.MousePos.y = height - vrEvent.data.mouse.y; + break; + case vr::VREvent_MouseButtonDown: + io.MouseDown[vrEvent.data.mouse.button == vr::VRMouseButton_Left ? 0 : 1] = true; + break; + case vr::VREvent_MouseButtonUp: + io.MouseDown[vrEvent.data.mouse.button == vr::VRMouseButton_Left ? 0 : 1] = false; + break; + case vr::VREvent_ScrollDiscrete: + io.MouseWheelH += vrEvent.data.scroll.xdelta * 360.0f * 8.0f; + io.MouseWheel += vrEvent.data.scroll.ydelta * 360.0f * 8.0f; + break; + case vr::VREvent_KeyboardDone: { + char buf[0x400]; + vr::VROverlay()->GetKeyboardText(buf, sizeof buf); + ImGui::SetActiveText(buf, sizeof buf); + keyboardJustClosed = true; + break; + } + case vr::VREvent_Quit: + return; + } + } + } + + ImGui::GetIO().DisplaySize = ImVec2((float) fboTextureWidth, (float) fboTextureHeight); + + ImGui_ImplGlfw_SetReadMouseFromGlfw(!dashboardVisible); + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + BuildMainWindow(dashboardVisible); + + ImGui::Render(); + + glBindFramebuffer(GL_FRAMEBUFFER, fboHandle); + glViewport(0, 0, fboTextureWidth, fboTextureHeight); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + if (width && height) + { + glBindFramebuffer(GL_READ_FRAMEBUFFER, fboHandle); + glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + glfwSwapBuffers(glfwWindow); + } + + if (dashboardVisible) + { + vr::Texture_t vrTex; + vrTex.eType = vr::TextureType_OpenGL; + vrTex.eColorSpace = vr::ColorSpace_Auto; + + vrTex.handle = (void *) +#if defined _WIN64 || defined _LP64 + (uint64_t) +#endif + fboTextureHandle; + + vr::HmdVector2_t mouseScale = { (float) fboTextureWidth, (float) fboTextureHeight }; + + vr::VROverlay()->SetOverlayTexture(overlayMainHandle, &vrTex); + vr::VROverlay()->SetOverlayMouseScale(overlayMainHandle, &mouseScale); + } + + const double dashboardInterval = 1.0 / 90.0; // fps + double waitEventsTimeout = CalCtx.wantedUpdateInterval; + + if (dashboardVisible && waitEventsTimeout > dashboardInterval) + waitEventsTimeout = dashboardInterval; + + glfwWaitEventsTimeout(waitEventsTimeout); + } +} + +using convert_t = std::codecvt_utf8; +std::wstring_convert strconverter; + +std::string to_string(std::wstring wstr) +{ + return strconverter.to_bytes(wstr); +} + +std::wstring to_wstring(std::string str) +{ + return strconverter.from_bytes(str); +} + +static void HandleCommandLineFunction(wchar_t const * lpCmdLine); +int main(int argc, char ** argv) +{ + const int max_path = 2048; + char cwd[max_path] = {0}; + wchar_t const * lpCmdLine; + std::wstring wide; + for(int i=1; i(max_path); + unsigned int pathLen; + vr::VR_GetRuntimePath(cruntimePath.get(), max_path, &pathLen); + + const int cmdLength = 8196; + char cmd[cmdLength]; + + snprintf(cmd, cmdLength, "python " DRIVER_INSTALLER_PATH "/driverInstall.py --toInstall " DRIVER_MANIFEST_PATH " --vrpathreg %s/bin/vrpathreg.sh", cruntimePath.get()); + printf("cmd: %s\n", cmd); + system(cmd); + + vr::VR_Shutdown(); + exit(0); +} + +void UninstallDriver(int max_path){ + auto vrErr = vr::VRInitError_None; + vr::VR_Init(&vrErr, vr::VRApplication_Utility); + if (vrErr != vr::VRInitError_None) + { + fprintf(stderr, "Failed to initialize OpenVR: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(vrErr)); + vr::VR_Shutdown(); + exit(-2); + } + + auto cruntimePath = std::make_unique(max_path); + unsigned int pathLen; + vr::VR_GetRuntimePath(cruntimePath.get(), max_path, &pathLen); + + const int cmdLength = 8196; + char cmd[cmdLength]; + + snprintf(cmd, cmdLength, "\"%s/bin/vrpathreg.sh\" removedriverwithname 01spacecalibrator", cruntimePath.get()); + printf("cmd: %s\n", cmd); + + vr::VR_Shutdown(); + exit(0); +} + +static void HandleCommandLineFunction(wchar_t const * lpCmdLine, char * cwd) +{ + const int max_path = 2048; + if (StringMatch(lpCmdLine, L"-help") || StringMatch(lpCmdLine, L"-h")) + { + std::cout << "usage - OpenVR SpaceCalibrator, only pick one option" << std::endl; + std::cout << "-openvrpath print runtime path of openvr" << std::endl; + std::cout << "-installmanifest install the application vrmanifest" << std::endl; + std::cout << "-removemanifest remove the application vrmanifest" << std::endl; + std::cout << "-activatemultipledrivers enable multiple drivers in steamvr" << std::endl; + //Note that the next 2 are not on the windows build + std::cout << "-installdriver install the steam vr driver." << std::endl; + std::cout << "-uninstalldriver uninstall the steam vr driver." << std::endl; + std::cout << "-help -h print this message" << std::endl; + exit(0); + } + else if (StringMatch(lpCmdLine, L"-openvrpath")) + { + char cruntimePath[max_path] = { 0 }; + HandleCommandLine::OpenVRPath(cruntimePath, max_path); + } + else if (StringMatch(lpCmdLine, L"-installmanifest")) + { + HandleCommandLine::InstallManifest(cwd, max_path); + } + else if (StringMatch(lpCmdLine, L"-removemanifest")) + { + HandleCommandLine::RemoveManifest(cwd); + } + else if (StringMatch(lpCmdLine, L"-activatemultipledrivers")) + { + HandleCommandLine::ActivateMultipleDrivers(); + } + else if (StringMatch(lpCmdLine, L"-installdriver")) + { + InstallDriver(max_path); + } + else if (StringMatch(lpCmdLine, L"-uninstalldriver")) + { + UninstallDriver(max_path); + } +} diff --git a/OpenVR-SpaceCalibratorDriver/compat.cpp b/OpenVR-SpaceCalibratorDriver/compat.cpp deleted file mode 100644 index 5bc82aaa..00000000 --- a/OpenVR-SpaceCalibratorDriver/compat.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include "compat.h" -#include - -std::unordered_map functionMap; - - -void MessageBox(void *, wchar_t const * msg, wchar_t const * title, int /* trash */ ){ - std::wcerr << "Messagebox: " << title << ": " << msg << std::endl; -} - -/* -void MessageBox(void *, char* msg, char * title, int ){ - std::cerr << "Messagebox: " << title << ": " << msg << std::endl; -} */ - - -int MH_Initialize(){ - return 0; -} - -char const * MH_StatusToString(int err){ - switch(err){ - case 0: - return "No Error"; - default: - return "Unkonwn"; - } -} - -void MH_Uninitialize() -{ -} - -void MH_RemoveHook(void* /* thing */){ -} -int MH_EnableHook(void* /* thing */){ - return 1; -} -int MH_CreateHook(void* /* a */, void* /* b */, LPVOID* /* fun */){ - return 1; -} - diff --git a/OpenVR-SpaceCalibratorDriver/compat.h b/OpenVR-SpaceCalibratorDriver/compat.h deleted file mode 100644 index 09717e32..00000000 --- a/OpenVR-SpaceCalibratorDriver/compat.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#ifdef __linux__ - -#include - -#define WINAPI -typedef void* LPVOID; - - -typedef struct _OVERLAPPED { - void * nothing; -} OVERLAPPED; - -typedef void* HANDLE; -typedef bool BOOL; -typedef uint32_t DWORD; -typedef OVERLAPPED* LPOVERLAPPED; -typedef unsigned char BYTE; -typedef int LSTATUS; -typedef wchar_t * LPWSTR; - -#define MAX_PATH 1024 - -#define MH_OK 0 -#define FALSE false -#define TRUE true - -#define ERROR_BROKEN_PIPE 1 -#define ERROR_SUCCESS 0 -#define INVALID_HANDLE_VALUE nullptr - -void MessageBox(void *, wchar_t const * msg, wchar_t const * title, int trash); - -int MH_Initialize(); -char const * MH_StatusToString(int err); -void MH_Uninitialize(); -void MH_RemoveHook(void* thing); -int MH_EnableHook(void* thing); -int MH_CreateHook(void* a, void* b, LPVOID* fun); - -#else -//NOP not needed in windows -#endif diff --git a/Version.h b/Version.h index 4a569578..40847b38 100644 --- a/Version.h +++ b/Version.h @@ -1,7 +1,3 @@ #pragma once -#if !defined(_WIN32) && !defined(_WIN64) -#define SPACECAL_VERSION_STRING "1.4-LINUX" -#else #define SPACECAL_VERSION_STRING "1.4" -#endif From e6c76e1befd621cb13f85e125b7e2e1b338469ea Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Tue, 18 Oct 2022 21:50:56 -0500 Subject: [PATCH 21/27] Builds again after stripping many preprocessor statements --- CMakeLists.txt | 7 +- OpenVR-SpaceCalibrator/Calibration.cpp | 1 - OpenVR-SpaceCalibrator/Calibration.h | 1 + .../Configuration_linux.cpp | 3 - OpenVR-SpaceCalibrator/IPCClient.cpp | 2 +- OpenVR-SpaceCalibrator/IPCClient.h | 1 - .../OpenVR-SpaceCalibrator.cpp | 83 +-- .../OpenVR-SpaceCalibrator.h | 6 + .../OpenVR-SpaceCalibrator_linux.cpp | 492 ------------------ OpenVR-SpaceCalibrator/UserInterface.cpp | 1 - OpenVR-SpaceCalibrator/main_linux.cpp | 142 +++++ OpenVR-SpaceCalibrator/main_win.cpp | 82 +++ OpenVR-SpaceCalibrator/stdafx.h | 6 - OpenVR-SpaceCalibratorDriver/IPCServer.h | 1 - .../InterfaceHookInjector.cpp | 4 - 15 files changed, 248 insertions(+), 584 deletions(-) create mode 100644 OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.h delete mode 100644 OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator_linux.cpp create mode 100644 OpenVR-SpaceCalibrator/main_linux.cpp create mode 100644 OpenVR-SpaceCalibrator/main_win.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index adac6470..a0f2f710 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,8 @@ set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED True) add_executable(OpenVR-SpaceCalibrator - OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator_linux.cpp + OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp + OpenVR-SpaceCalibrator/main_linux.cpp OpenVR-SpaceCalibrator/Calibration.cpp OpenVR-SpaceCalibrator/Configuration_linux.cpp OpenVR-SpaceCalibrator/HandleCommandLine_linux.cpp @@ -42,8 +43,6 @@ add_executable(OpenVR-SpaceCalibrator 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) @@ -54,10 +53,8 @@ add_library( 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 ) diff --git a/OpenVR-SpaceCalibrator/Calibration.cpp b/OpenVR-SpaceCalibrator/Calibration.cpp index cac0fbb9..2d7da975 100644 --- a/OpenVR-SpaceCalibrator/Calibration.cpp +++ b/OpenVR-SpaceCalibrator/Calibration.cpp @@ -1,4 +1,3 @@ -#include "stdafx.h" #include "Calibration.h" #include "Configuration.h" #include "IPCClient.h" diff --git a/OpenVR-SpaceCalibrator/Calibration.h b/OpenVR-SpaceCalibrator/Calibration.h index 46739c63..9d73613a 100644 --- a/OpenVR-SpaceCalibrator/Calibration.h +++ b/OpenVR-SpaceCalibrator/Calibration.h @@ -3,6 +3,7 @@ #include #include #include +#include enum class CalibrationState { diff --git a/OpenVR-SpaceCalibrator/Configuration_linux.cpp b/OpenVR-SpaceCalibrator/Configuration_linux.cpp index c146c9ce..21478b5c 100644 --- a/OpenVR-SpaceCalibrator/Configuration_linux.cpp +++ b/OpenVR-SpaceCalibrator/Configuration_linux.cpp @@ -1,4 +1,3 @@ -#include "stdafx.h" #include "Configuration.h" #include @@ -11,13 +10,11 @@ #include "Logging.h" -#ifdef __linux__ #include #include #include #include "StaticConfig.h" #define LINUX_CONFIG_FILE "spacecal-config.json" -#endif static picojson::array FloatArray(const float *buf, int numFloats) { diff --git a/OpenVR-SpaceCalibrator/IPCClient.cpp b/OpenVR-SpaceCalibrator/IPCClient.cpp index 073dc087..f64fddf3 100644 --- a/OpenVR-SpaceCalibrator/IPCClient.cpp +++ b/OpenVR-SpaceCalibrator/IPCClient.cpp @@ -1,10 +1,10 @@ -#include "stdafx.h" #include "IPCClient.h" #ifdef __linux__ #include "Comms.h" #endif #include +#include #ifdef __linux__ // NOP diff --git a/OpenVR-SpaceCalibrator/IPCClient.h b/OpenVR-SpaceCalibrator/IPCClient.h index e2479c09..1044e4b5 100644 --- a/OpenVR-SpaceCalibrator/IPCClient.h +++ b/OpenVR-SpaceCalibrator/IPCClient.h @@ -1,7 +1,6 @@ #pragma once #ifdef __linux__ -#include "compat.h" #include "Comms.h" #else #endif diff --git a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp index 5281860c..9728a96e 100644 --- a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp +++ b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp @@ -1,8 +1,9 @@ -#include "stdafx.h" -#include "Calibration.h" +#include "Calibration.h" #include "Configuration.h" #include "EmbeddedFiles.h" #include "UserInterface.h" +#include "OpenVR-SpaceCalibrator.h" +#include "iostream" #include #include @@ -10,31 +11,6 @@ #include #include #include -#include -#include "HandleCommandLine.h" - -#pragma comment(linker,"\"/manifestdependency:type='win32' \ -name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ -processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") - -#define OPENVR_APPLICATION_KEY "pushrax.SpaceCalibrator" - -extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; -extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001; - -void CreateConsole() -{ - static bool created = false; - if (!created) - { - AllocConsole(); - FILE *file = nullptr; - freopen_s(&file, "CONIN$", "r", stdin); - freopen_s(&file, "CONOUT$", "w", stdout); - freopen_s(&file, "CONOUT$", "w", stderr); - created = true; - } -} //#define DEBUG_LOGS @@ -48,15 +24,11 @@ void openGLDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, fprintf(stderr, "OpenGL Debug %u: %.*s\n", id, length, message); } -static void HandleCommandLine(LPWSTR lpCmdLine); - static GLFWwindow *glfwWindow = nullptr; static vr::VROverlayHandle_t overlayMainHandle = 0, overlayThumbnailHandle = 0; static GLuint fboHandle = 0, fboTextureHandle = 0; static int fboTextureWidth = 0, fboTextureHeight = 0; -static char cwd[MAX_PATH]; - void CreateGLFWWindow() { glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); @@ -117,7 +89,7 @@ void CreateGLFWWindow() } } -void TryCreateVROverlay() +void TryCreateVROverlay(char const * cwd) { if (overlayMainHandle || !vr::VROverlay()) return; @@ -203,11 +175,11 @@ void InitVR() ActivateMultipleDrivers(); } -void RunLoop() +void RunLoop(char const * cwd) { while (!glfwWindowShouldClose(glfwWindow)) { - TryCreateVROverlay(); + TryCreateVROverlay(cwd); double time = glfwGetTime(); CalibrationTick(time); @@ -340,29 +312,24 @@ void RunLoop() } } -int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) -{ - _getcwd(cwd, MAX_PATH); - HandleCommandLine(lpCmdLine); - -#ifdef DEBUG_LOGS - CreateConsole(); -#endif - +int MainApplication(char const * const cwd, InitErrorCallback errCB){ if (!glfwInit()) { - MessageBox(nullptr, L"Failed to initialize GLFW", L"", 0); + errCB("Failed to initialize GLFW"); return 0; } glfwSetErrorCallback(GLFWErrorCallback); + try { InitVR(); CreateGLFWWindow(); InitCalibrator(); LoadProfile(CalCtx); - RunLoop(); + + + RunLoop(cwd); vr::VR_Shutdown(); @@ -378,10 +345,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance } catch (std::runtime_error &e) { - std::cerr << "Runtime error: " << e.what() << std::endl; - wchar_t message[1024]; - swprintf(message, 1024, L"%hs", e.what()); - MessageBox(nullptr, message, L"Runtime Error", 0); + errCB(e.what()); } if (glfwWindow) @@ -391,23 +355,4 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance return 0; } -static void HandleCommandLine(LPWSTR lpCmdLine) -{ - if (lstrcmp(lpCmdLine, L"-openvrpath") == 0) - { - char cruntimePath[MAX_PATH] = { 0 }; - HandleCommandLine::OpenVRPath(cruntimePath, MAX_PATH); - } - else if (lstrcmp(lpCmdLine, L"-installmanifest") == 0) - { - HandleCommandLine::InstallManifest(cwd, MAX_PATH); - } - else if (lstrcmp(lpCmdLine, L"-removemanifest") == 0) - { - HandleCommandLine::RemoveManifest(cwd); - } - else if (lstrcmp(lpCmdLine, L"-activatemultipledrivers") == 0) - { - HandleCommandLine::ActivateMultipleDrivers(); - } -} + diff --git a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.h b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.h new file mode 100644 index 00000000..c66a7c5b --- /dev/null +++ b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.h @@ -0,0 +1,6 @@ +#pragma once + +typedef void (*InitErrorCallback)(char const * ); + +int MainApplication(char const * const cwd, InitErrorCallback cb); + diff --git a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator_linux.cpp b/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator_linux.cpp deleted file mode 100644 index 75fac955..00000000 --- a/OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator_linux.cpp +++ /dev/null @@ -1,492 +0,0 @@ -#include "stdafx.h" -#include "Calibration.h" -#include "Configuration.h" -#include "EmbeddedFiles.h" -#include "UserInterface.h" - -#include -#include -#include -#include "GL/gl3w.h" - -#include - -#include "HandleCommandLine.h" - -#include -#include -#include - -#include -#include - -#include "StaticConfig.h" - -void GLFWErrorCallback(int error, const char* description) -{ - fprintf(stderr, "GLFW Error %d: %s\n", error, description); -} - -void openGLDebugCallback(GLenum /* source */, GLenum /* type */, GLuint id, GLenum /* severity */, GLsizei length, const GLchar *message, const void * /* userParam */ ) -{ - fprintf(stderr, "OpenGL Debug %u: %.*s\n", id, length, message); -} - -static GLFWwindow *glfwWindow = nullptr; -static vr::VROverlayHandle_t overlayMainHandle = 0, overlayThumbnailHandle = 0; -static GLuint fboHandle = 0, fboTextureHandle = 0; -static int fboTextureWidth = 0, fboTextureHeight = 0; - -void CreateGLFWWindow() -{ - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - glfwWindowHint(GLFW_RESIZABLE, false); - -#ifdef DEBUG_LOGS - glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); -#endif - - fboTextureWidth = 1200; - fboTextureHeight = 800; - - glfwWindow = glfwCreateWindow(fboTextureWidth, fboTextureHeight, "OpenVR-SpaceCalibrator", NULL, NULL); - if (!glfwWindow) - throw std::runtime_error("Failed to create window"); - - glfwMakeContextCurrent(glfwWindow); - glfwSwapInterval(1); - gl3wInit(); - - glfwIconifyWindow(glfwWindow); - -#ifdef DEBUG_LOGS - glDebugMessageCallback(openGLDebugCallback, nullptr); - glEnable(GL_DEBUG_OUTPUT); -#endif - - ImGui::CreateContext(); - ImGuiIO &io = ImGui::GetIO(); - io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; - io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; - io.IniFilename = nullptr; - io.Fonts->AddFontFromMemoryCompressedTTF(DroidSans_compressed_data, DroidSans_compressed_size, 24.0f); - - ImGui_ImplGlfw_InitForOpenGL(glfwWindow, true); - ImGui_ImplOpenGL3_Init("#version 330"); - - ImGui::StyleColorsDark(); - - glGenTextures(1, &fboTextureHandle); - glBindTexture(GL_TEXTURE_2D, fboTextureHandle); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, fboTextureWidth, fboTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - glGenFramebuffers(1, &fboHandle); - glBindFramebuffer(GL_FRAMEBUFFER, fboHandle); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, fboTextureHandle, 0); - - GLenum drawBuffers[1] = { GL_COLOR_ATTACHMENT0 }; - glDrawBuffers(1, drawBuffers); - - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - { - throw std::runtime_error("OpenGL framebuffer incomplete"); - } -} - -void TryCreateVROverlay() -{ - if (overlayMainHandle || !vr::VROverlay()) - return; - - vr::VROverlayError error = vr::VROverlay()->CreateDashboardOverlay( - "pushrax.SpaceCalibrator", "Space Cal", - &overlayMainHandle, &overlayThumbnailHandle - ); - - if (error == vr::VROverlayError_KeyInUse) - { - throw std::runtime_error("Another instance of OpenVR Space Calibrator is already running"); - } - else if (error != vr::VROverlayError_None) - { - throw std::runtime_error("Error creating VR overlay: " + std::string(vr::VROverlay()->GetOverlayErrorNameFromEnum(error))); - } - - vr::VROverlay()->SetOverlayWidthInMeters(overlayMainHandle, 3.0f); - vr::VROverlay()->SetOverlayInputMethod(overlayMainHandle, vr::VROverlayInputMethod_Mouse); - vr::VROverlay()->SetOverlayFlag(overlayMainHandle, vr::VROverlayFlags_SendVRDiscreteScrollEvents, true); - - std::string iconPath = cwd; - iconPath += "\\icon.png"; - vr::VROverlay()->SetOverlayFromFile(overlayThumbnailHandle, iconPath.c_str()); -} - -void ActivateMultipleDrivers() -{ - vr::EVRSettingsError vrSettingsError; - bool enabled = vr::VRSettings()->GetBool(vr::k_pch_SteamVR_Section, vr::k_pch_SteamVR_ActivateMultipleDrivers_Bool, &vrSettingsError); - - if (vrSettingsError != vr::VRSettingsError_None) - { - std::string err = "Could not read \"" + std::string(vr::k_pch_SteamVR_ActivateMultipleDrivers_Bool) + "\" setting: " - + vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - - throw std::runtime_error(err); - } - - if (!enabled) - { - vr::VRSettings()->SetBool(vr::k_pch_SteamVR_Section, vr::k_pch_SteamVR_ActivateMultipleDrivers_Bool, true, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) - { - std::string err = "Could not set \"" + std::string(vr::k_pch_SteamVR_ActivateMultipleDrivers_Bool) + "\" setting: " - + vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - - throw std::runtime_error(err); - } - - std::cerr << "Enabled \"" << vr::k_pch_SteamVR_ActivateMultipleDrivers_Bool << "\" setting" << std::endl; - } - else - { - std::cerr << "\"" << vr::k_pch_SteamVR_ActivateMultipleDrivers_Bool << "\" setting previously enabled" << std::endl; - } -} - -void InitVR() -{ - auto initError = vr::VRInitError_None; - vr::VR_Init(&initError, vr::VRApplication_Other); - if (initError != vr::VRInitError_None) - { - auto error = vr::VR_GetVRInitErrorAsEnglishDescription(initError); - throw std::runtime_error("OpenVR error:" + std::string(error)); - } - - if (!vr::VR_IsInterfaceVersionValid(vr::IVRSystem_Version)) - { - throw std::runtime_error("OpenVR error: Outdated IVRSystem_Version"); - } - else if (!vr::VR_IsInterfaceVersionValid(vr::IVRSettings_Version)) - { - throw std::runtime_error("OpenVR error: Outdated IVRSettings_Version"); - } - else if (!vr::VR_IsInterfaceVersionValid(vr::IVROverlay_Version)) - { - throw std::runtime_error("OpenVR error: Outdated IVROverlay_Version"); - } - - ActivateMultipleDrivers(); -} - -void RunLoop() -{ - while (!glfwWindowShouldClose(glfwWindow)) - { - TryCreateVROverlay(); - - double time = glfwGetTime(); - CalibrationTick(time); - - bool dashboardVisible = false; - int width, height; - glfwGetFramebufferSize(glfwWindow, &width, &height); - - if (overlayMainHandle && vr::VROverlay()) - { - auto &io = ImGui::GetIO(); - dashboardVisible = vr::VROverlay()->IsActiveDashboardOverlay(overlayMainHandle); - - static bool keyboardOpen = false, keyboardJustClosed = false; - - // After closing the keyboard, this code waits one frame for ImGui to pick up the new text from SetActiveText - // before clearing the active widget. Then it waits another frame before allowing the keyboard to open again, - // otherwise it will do so instantly since WantTextInput is still true on the second frame. - if (keyboardJustClosed && keyboardOpen) - { - ImGui::ClearActiveID(); - keyboardOpen = false; - } - else if (keyboardJustClosed) - { - keyboardJustClosed = false; - } - else if (!io.WantTextInput) - { - // User might close the keyboard without hitting Done, so we unset the flag to allow it to open again. - keyboardOpen = false; - } - else if (io.WantTextInput && !keyboardOpen && !keyboardJustClosed) - { - char buf[0x400]; - ImGui::GetActiveText(buf, sizeof buf); - buf[0x3ff] = 0; - uint32_t unFlags = 0; // EKeyboardFlags - - vr::VROverlay()->ShowKeyboardForOverlay( - overlayMainHandle, vr::k_EGamepadTextInputModeNormal, vr::k_EGamepadTextInputLineModeSingleLine, - unFlags, "Space Calibrator Overlay", sizeof buf, buf, 0 - ); - keyboardOpen = true; - } - - vr::VREvent_t vrEvent; - while (vr::VROverlay()->PollNextOverlayEvent(overlayMainHandle, &vrEvent, sizeof(vrEvent))) - { - switch (vrEvent.eventType) { - case vr::VREvent_MouseMove: - io.MousePos.x = vrEvent.data.mouse.x; - //The mouse is flipped in linux - io.MousePos.y = height - vrEvent.data.mouse.y; - break; - case vr::VREvent_MouseButtonDown: - io.MouseDown[vrEvent.data.mouse.button == vr::VRMouseButton_Left ? 0 : 1] = true; - break; - case vr::VREvent_MouseButtonUp: - io.MouseDown[vrEvent.data.mouse.button == vr::VRMouseButton_Left ? 0 : 1] = false; - break; - case vr::VREvent_ScrollDiscrete: - io.MouseWheelH += vrEvent.data.scroll.xdelta * 360.0f * 8.0f; - io.MouseWheel += vrEvent.data.scroll.ydelta * 360.0f * 8.0f; - break; - case vr::VREvent_KeyboardDone: { - char buf[0x400]; - vr::VROverlay()->GetKeyboardText(buf, sizeof buf); - ImGui::SetActiveText(buf, sizeof buf); - keyboardJustClosed = true; - break; - } - case vr::VREvent_Quit: - return; - } - } - } - - ImGui::GetIO().DisplaySize = ImVec2((float) fboTextureWidth, (float) fboTextureHeight); - - ImGui_ImplGlfw_SetReadMouseFromGlfw(!dashboardVisible); - ImGui_ImplOpenGL3_NewFrame(); - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); - - BuildMainWindow(dashboardVisible); - - ImGui::Render(); - - glBindFramebuffer(GL_FRAMEBUFFER, fboHandle); - glViewport(0, 0, fboTextureWidth, fboTextureHeight); - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT); - - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - if (width && height) - { - glBindFramebuffer(GL_READ_FRAMEBUFFER, fboHandle); - glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); - glfwSwapBuffers(glfwWindow); - } - - if (dashboardVisible) - { - vr::Texture_t vrTex; - vrTex.eType = vr::TextureType_OpenGL; - vrTex.eColorSpace = vr::ColorSpace_Auto; - - vrTex.handle = (void *) -#if defined _WIN64 || defined _LP64 - (uint64_t) -#endif - fboTextureHandle; - - vr::HmdVector2_t mouseScale = { (float) fboTextureWidth, (float) fboTextureHeight }; - - vr::VROverlay()->SetOverlayTexture(overlayMainHandle, &vrTex); - vr::VROverlay()->SetOverlayMouseScale(overlayMainHandle, &mouseScale); - } - - const double dashboardInterval = 1.0 / 90.0; // fps - double waitEventsTimeout = CalCtx.wantedUpdateInterval; - - if (dashboardVisible && waitEventsTimeout > dashboardInterval) - waitEventsTimeout = dashboardInterval; - - glfwWaitEventsTimeout(waitEventsTimeout); - } -} - -using convert_t = std::codecvt_utf8; -std::wstring_convert strconverter; - -std::string to_string(std::wstring wstr) -{ - return strconverter.to_bytes(wstr); -} - -std::wstring to_wstring(std::string str) -{ - return strconverter.from_bytes(str); -} - -static void HandleCommandLineFunction(wchar_t const * lpCmdLine); -int main(int argc, char ** argv) -{ - const int max_path = 2048; - char cwd[max_path] = {0}; - wchar_t const * lpCmdLine; - std::wstring wide; - for(int i=1; i(max_path); - unsigned int pathLen; - vr::VR_GetRuntimePath(cruntimePath.get(), max_path, &pathLen); - - const int cmdLength = 8196; - char cmd[cmdLength]; - - snprintf(cmd, cmdLength, "python " DRIVER_INSTALLER_PATH "/driverInstall.py --toInstall " DRIVER_MANIFEST_PATH " --vrpathreg %s/bin/vrpathreg.sh", cruntimePath.get()); - printf("cmd: %s\n", cmd); - system(cmd); - - vr::VR_Shutdown(); - exit(0); -} - -void UninstallDriver(int max_path){ - auto vrErr = vr::VRInitError_None; - vr::VR_Init(&vrErr, vr::VRApplication_Utility); - if (vrErr != vr::VRInitError_None) - { - fprintf(stderr, "Failed to initialize OpenVR: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(vrErr)); - vr::VR_Shutdown(); - exit(-2); - } - - auto cruntimePath = std::make_unique(max_path); - unsigned int pathLen; - vr::VR_GetRuntimePath(cruntimePath.get(), max_path, &pathLen); - - const int cmdLength = 8196; - char cmd[cmdLength]; - - snprintf(cmd, cmdLength, "\"%s/bin/vrpathreg.sh\" removedriverwithname 01spacecalibrator", cruntimePath.get()); - printf("cmd: %s\n", cmd); - - vr::VR_Shutdown(); - exit(0); -} - -static void HandleCommandLineFunction(wchar_t const * lpCmdLine, char * cwd) -{ - const int max_path = 2048; - if (StringMatch(lpCmdLine, L"-help") || StringMatch(lpCmdLine, L"-h")) - { - std::cout << "usage - OpenVR SpaceCalibrator, only pick one option" << std::endl; - std::cout << "-openvrpath print runtime path of openvr" << std::endl; - std::cout << "-installmanifest install the application vrmanifest" << std::endl; - std::cout << "-removemanifest remove the application vrmanifest" << std::endl; - std::cout << "-activatemultipledrivers enable multiple drivers in steamvr" << std::endl; - //Note that the next 2 are not on the windows build - std::cout << "-installdriver install the steam vr driver." << std::endl; - std::cout << "-uninstalldriver uninstall the steam vr driver." << std::endl; - std::cout << "-help -h print this message" << std::endl; - exit(0); - } - else if (StringMatch(lpCmdLine, L"-openvrpath")) - { - char cruntimePath[max_path] = { 0 }; - HandleCommandLine::OpenVRPath(cruntimePath, max_path); - } - else if (StringMatch(lpCmdLine, L"-installmanifest")) - { - HandleCommandLine::InstallManifest(cwd, max_path); - } - else if (StringMatch(lpCmdLine, L"-removemanifest")) - { - HandleCommandLine::RemoveManifest(cwd); - } - else if (StringMatch(lpCmdLine, L"-activatemultipledrivers")) - { - HandleCommandLine::ActivateMultipleDrivers(); - } - else if (StringMatch(lpCmdLine, L"-installdriver")) - { - InstallDriver(max_path); - } - else if (StringMatch(lpCmdLine, L"-uninstalldriver")) - { - UninstallDriver(max_path); - } -} diff --git a/OpenVR-SpaceCalibrator/UserInterface.cpp b/OpenVR-SpaceCalibrator/UserInterface.cpp index 94122f91..8a2df673 100644 --- a/OpenVR-SpaceCalibrator/UserInterface.cpp +++ b/OpenVR-SpaceCalibrator/UserInterface.cpp @@ -1,4 +1,3 @@ -#include "stdafx.h" #include "UserInterface.h" #include "Calibration.h" #include "Configuration.h" diff --git a/OpenVR-SpaceCalibrator/main_linux.cpp b/OpenVR-SpaceCalibrator/main_linux.cpp new file mode 100644 index 00000000..6f7aecc0 --- /dev/null +++ b/OpenVR-SpaceCalibrator/main_linux.cpp @@ -0,0 +1,142 @@ +#include "Calibration.h" +#include "Configuration.h" +#include "EmbeddedFiles.h" +#include "UserInterface.h" + +#include "OpenVR-SpaceCalibrator.h" +#include +#include +#include +#include "GL/gl3w.h" + +#include + +#include "HandleCommandLine.h" + +#include +#include +#include + +#include +#include + +#include "StaticConfig.h" + +void printError(char const * err){ + std::cerr<(max_path); + unsigned int pathLen; + vr::VR_GetRuntimePath(cruntimePath.get(), max_path, &pathLen); + + const int cmdLength = 8196; + char cmd[cmdLength]; + + snprintf(cmd, cmdLength, "python " DRIVER_INSTALLER_PATH "/driverInstall.py --toInstall " DRIVER_MANIFEST_PATH " --vrpathreg %s/bin/vrpathreg.sh", cruntimePath.get()); + printf("cmd: %s\n", cmd); + system(cmd); + + vr::VR_Shutdown(); + exit(0); +} + +void UninstallDriver(int max_path){ + auto vrErr = vr::VRInitError_None; + vr::VR_Init(&vrErr, vr::VRApplication_Utility); + if (vrErr != vr::VRInitError_None) + { + fprintf(stderr, "Failed to initialize OpenVR: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(vrErr)); + vr::VR_Shutdown(); + exit(-2); + } + + auto cruntimePath = std::make_unique(max_path); + unsigned int pathLen; + vr::VR_GetRuntimePath(cruntimePath.get(), max_path, &pathLen); + + const int cmdLength = 8196; + char cmd[cmdLength]; + + snprintf(cmd, cmdLength, "\"%s/bin/vrpathreg.sh\" removedriverwithname 01spacecalibrator", cruntimePath.get()); + printf("cmd: %s\n", cmd); + + vr::VR_Shutdown(); + exit(0); +} + +static void HandleCommandLineFunction(char const * cmdLine, char * cwd) +{ + const int max_path = 2048; + if (!strcmp(cmdLine, "-help") || !strcmp(cmdLine, "-h")) + { + std::cout << "usage - OpenVR SpaceCalibrator, only pick one option" << std::endl; + std::cout << "-openvrpath print runtime path of openvr" << std::endl; + std::cout << "-installmanifest install the application vrmanifest" << std::endl; + std::cout << "-removemanifest remove the application vrmanifest" << std::endl; + std::cout << "-activatemultipledrivers enable multiple drivers in steamvr" << std::endl; + //Note that the next 2 are not on the windows build + std::cout << "-installdriver install the steam vr driver." << std::endl; + std::cout << "-uninstalldriver uninstall the steam vr driver." << std::endl; + std::cout << "-help -h print this message" << std::endl; + exit(0); + } + else if (!strcmp(cmdLine, "-openvrpath")) + { + char cruntimePath[max_path] = { 0 }; + HandleCommandLine::OpenVRPath(cruntimePath, max_path); + } + else if (!strcmp(cmdLine, "-installmanifest")) + { + HandleCommandLine::InstallManifest(cwd, max_path); + } + else if (!strcmp(cmdLine, "-removemanifest")) + { + HandleCommandLine::RemoveManifest(cwd); + } + else if (!strcmp(cmdLine, "-activatemultipledrivers")) + { + HandleCommandLine::ActivateMultipleDrivers(); + } + else if (!strcmp(cmdLine, "-installdriver")) + { + InstallDriver(max_path); + } + else if (!strcmp(cmdLine, "-uninstalldriver")) + { + UninstallDriver(max_path); + } +} + diff --git a/OpenVR-SpaceCalibrator/main_win.cpp b/OpenVR-SpaceCalibrator/main_win.cpp new file mode 100644 index 00000000..ba4e0fef --- /dev/null +++ b/OpenVR-SpaceCalibrator/main_win.cpp @@ -0,0 +1,82 @@ +#include "stdafx.h" + +#include "OpenVR-SpaceCalibrator.h" + +#include "Calibration.h" +#include "Configuration.h" +#include "EmbeddedFiles.h" +#include "UserInterface.h" + +#include +#include +#include +#include +#include +#include +#include +#include "HandleCommandLine.h" + +#pragma comment(linker,"\"/manifestdependency:type='win32' \ +name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ +processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") + +extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; +extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001; + +static char cwd[MAX_PATH]; + +static void HandleCommandLineFunction(LPWSTR lpCmdLine) +{ + if (lstrcmp(lpCmdLine, L"-openvrpath") == 0) + { + char cruntimePath[MAX_PATH] = { 0 }; + HandleCommandLine::OpenVRPath(cruntimePath, MAX_PATH); + } + else if (lstrcmp(lpCmdLine, L"-installmanifest") == 0) + { + HandleCommandLine::InstallManifest(cwd, MAX_PATH); + } + else if (lstrcmp(lpCmdLine, L"-removemanifest") == 0) + { + HandleCommandLine::RemoveManifest(cwd); + } + else if (lstrcmp(lpCmdLine, L"-activatemultipledrivers") == 0) + { + HandleCommandLine::ActivateMultipleDrivers(); + } +} + +void CreateConsole() +{ + static bool created = false; + if (!created) + { + AllocConsole(); + FILE *file = nullptr; + freopen_s(&file, "CONIN$", "r", stdin); + freopen_s(&file, "CONOUT$", "w", stdout); + freopen_s(&file, "CONOUT$", "w", stderr); + created = true; + } +} + +void MessageBoxCallback(char * err){ + std::cerr << "Runtime error: " << err << std::endl; + wchar_t message[1024]; + swprintf(message, 1024, L"%hs", err); + MessageBox(nullptr, message, L"Runtime Error", 0); +} + +int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) +{ + _getcwd(cwd, MAX_PATH); + HandleCommandLineFunction(lpCmdLine); + +#ifdef DEBUG_LOGS + CreateConsole(); +#endif + + return MainApplication(cwd, MessageBoxCallback); +} + + diff --git a/OpenVR-SpaceCalibrator/stdafx.h b/OpenVR-SpaceCalibrator/stdafx.h index 0c0fa62b..e74d9c8d 100644 --- a/OpenVR-SpaceCalibrator/stdafx.h +++ b/OpenVR-SpaceCalibrator/stdafx.h @@ -1,15 +1,9 @@ #pragma once -#ifdef __linux__ -#include -#include "compat.h" - -#else #include "targetver.h" #define WIN32_LEAN_AND_MEAN #include #include -#endif #include #include diff --git a/OpenVR-SpaceCalibratorDriver/IPCServer.h b/OpenVR-SpaceCalibratorDriver/IPCServer.h index 28805117..924f1d0d 100644 --- a/OpenVR-SpaceCalibratorDriver/IPCServer.h +++ b/OpenVR-SpaceCalibratorDriver/IPCServer.h @@ -1,7 +1,6 @@ #pragma once #include "../Protocol.h" -#include "compat.h" #include #include diff --git a/OpenVR-SpaceCalibratorDriver/InterfaceHookInjector.cpp b/OpenVR-SpaceCalibratorDriver/InterfaceHookInjector.cpp index 9b744f9a..2c461541 100644 --- a/OpenVR-SpaceCalibratorDriver/InterfaceHookInjector.cpp +++ b/OpenVR-SpaceCalibratorDriver/InterfaceHookInjector.cpp @@ -4,10 +4,6 @@ #include "Hooking.h" -#ifdef __linux__ -#include "compat.h" -#endif - static ServerTrackedDeviceProvider *Driver = nullptr; static Hook From e5087a03bb51a4e90bd55b9a3fa99e3c9c2f1f1f Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Fri, 21 Oct 2022 20:59:03 -0500 Subject: [PATCH 22/27] Linux changes! --- CMakeLists.txt | 4 +- OpenVR-SpaceCalibrator/IPCClient_linux.cpp | 129 +++++++++ .../IPCServer_linux.cpp | 62 +++++ .../IPCServer_win.cpp | 247 ++++++++++++++++++ 4 files changed, 440 insertions(+), 2 deletions(-) create mode 100644 OpenVR-SpaceCalibrator/IPCClient_linux.cpp create mode 100644 OpenVR-SpaceCalibratorDriver/IPCServer_linux.cpp create mode 100644 OpenVR-SpaceCalibratorDriver/IPCServer_win.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a0f2f710..7bc3b903 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ add_executable(OpenVR-SpaceCalibrator OpenVR-SpaceCalibrator/Configuration_linux.cpp OpenVR-SpaceCalibrator/HandleCommandLine_linux.cpp OpenVR-SpaceCalibrator/EmbeddedFiles.cpp - OpenVR-SpaceCalibrator/IPCClient.cpp + OpenVR-SpaceCalibrator/IPCClient_linux.cpp OpenVR-SpaceCalibrator/OpenVR-SpaceCalibrator.cpp OpenVR-SpaceCalibrator/UserInterface.cpp ./OpenVR-SpaceCalibratorDriver/Logging.cpp @@ -52,7 +52,7 @@ add_library( SHARED OpenVR-SpaceCalibratorDriver/OpenVR-SpaceCalibratorDriver.cpp OpenVR-SpaceCalibratorDriver/Hooking.cpp - OpenVR-SpaceCalibratorDriver/IPCServer.cpp + OpenVR-SpaceCalibratorDriver/IPCServer_linux.cpp OpenVR-SpaceCalibratorDriver/Logging.cpp OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.cpp OpenVR-SpaceCalibratorDriver/dllmain.cpp diff --git a/OpenVR-SpaceCalibrator/IPCClient_linux.cpp b/OpenVR-SpaceCalibrator/IPCClient_linux.cpp new file mode 100644 index 00000000..f64fddf3 --- /dev/null +++ b/OpenVR-SpaceCalibrator/IPCClient_linux.cpp @@ -0,0 +1,129 @@ +#include "IPCClient.h" +#ifdef __linux__ +#include "Comms.h" +#endif + +#include +#include + +#ifdef __linux__ +// NOP +#else +static std::string LastErrorString(DWORD lastError) +{ + LPSTR buffer = nullptr; + size_t size = FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, lastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, NULL + ); + + std::string message(buffer, size); + LocalFree(buffer); + return message; +} +#endif + +IPCClient::~IPCClient() +{ +#ifdef __linux__ + //NOP +#else + if (pipe && pipe != INVALID_HANDLE_VALUE) + CloseHandle(pipe); +#endif +} + +void IPCClient::Connect() +{ +#ifdef __linux__ +#else + LPTSTR pipeName = TEXT(OPENVR_SPACECALIBRATOR_PIPE_NAME); + + WaitNamedPipe(pipeName, 1000); + pipe = CreateFile(pipeName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); + + if (pipe == INVALID_HANDLE_VALUE) + { + throw std::runtime_error("Space Calibrator driver unavailable. Make sure SteamVR is running, and the Space Calibrator addon is enabled in SteamVR settings."); + } + + DWORD mode = PIPE_READMODE_MESSAGE; + if (!SetNamedPipeHandleState(pipe, &mode, 0, 0)) + { + throw std::runtime_error("Couldn't set pipe mode. Error: " + LastErrorString(GetLastError())); + } +#endif + auto response = SendBlocking(protocol::Request(protocol::RequestHandshake)); + if (response.type != protocol::ResponseHandshake || response.protocol.version != protocol::Version) + { + throw std::runtime_error( + "Incorrect driver version installed, try reinstalling OpenVR-SpaceCalibrator. (Client: " + + std::to_string(protocol::Version) + + ", Driver: " + + std::to_string(response.protocol.version) + + ")" + ); + } +} + +protocol::Response IPCClient::SendBlocking(const protocol::Request &request) +{ +#ifdef __linux__ + for(int i=0; i<10; i++){ + Send(request); + try{ + return Receive(); + } catch (std::runtime_error &t) { + LOG("%s: %s", "Recv timeout failed", t.what()); + } + } + throw std::runtime_error("Fell through read loop"); +#else + Send(request); + return Receive(); +#endif +} + +void IPCClient::Send(const protocol::Request &request) +{ +#ifdef __linux__ + pipe.Send(request); +#else + DWORD bytesWritten; + BOOL success = WriteFile(pipe, &request, sizeof request, &bytesWritten, 0); + if (!success) + { + throw std::runtime_error("Error writing IPC request. Error: " + LastErrorString(GetLastError())); + } +#endif +} + +protocol::Response IPCClient::Receive() +{ + protocol::Response response(protocol::ResponseInvalid); +#ifdef __linux__ + if( pipe.Recv(&response) ) + return response; + else + throw std::runtime_error("No packet was received"); +#else + DWORD bytesRead; + + BOOL success = ReadFile(pipe, &response, sizeof response, &bytesRead, 0); + if (!success) + { + DWORD lastError = GetLastError(); + if (lastError != ERROR_MORE_DATA) + { + throw std::runtime_error("Error reading IPC response. Error: " + LastErrorString(lastError)); + } + } + + if (bytesRead != sizeof response) + { + throw std::runtime_error("Invalid IPC response with size " + std::to_string(bytesRead)); + } + + return response; +#endif +} diff --git a/OpenVR-SpaceCalibratorDriver/IPCServer_linux.cpp b/OpenVR-SpaceCalibratorDriver/IPCServer_linux.cpp new file mode 100644 index 00000000..f61a5cfe --- /dev/null +++ b/OpenVR-SpaceCalibratorDriver/IPCServer_linux.cpp @@ -0,0 +1,62 @@ +#include "IPCServer.h" +#include "Logging.h" +#include "ServerTrackedDeviceProvider.h" +#include "Comms.h" + +#include "" + +struct IPCServerImpl { +}; + +void IPCServer::HandleRequest(const protocol::Request &request, protocol::Response &response) +{ + switch (request.type) + { + case protocol::RequestHandshake: + response.type = protocol::ResponseHandshake; + response.protocol.version = protocol::Version; + break; + + case protocol::RequestSetDeviceTransform: + driver->SetDeviceTransform(request.setDeviceTransform); + response.type = protocol::ResponseSuccess; + break; + + default: + LOG("Invalid IPC request: %d", request.type); + break; + } +} + +IPCServer::~IPCServer() +{ + Stop(); +} + +void IPCServer::Run() +{ + mainThread = std::thread(RunThread, this); +} + +void IPCServer::Stop() +{ + TRACE("%s", "IPCServer::Stop()"); + if (!running) + return; + stop = true; +} +void IPCServer::RunThread(IPCServer *_this) +{ + Comms comms; + + protocol::Response response; + protocol::Request request; + + while(!_this->stop){ + comms.Recv(&request); + _this->HandleRequest(request, response); + comms.Send(response); + } + LOG("%s", "Stop requested"); +} + diff --git a/OpenVR-SpaceCalibratorDriver/IPCServer_win.cpp b/OpenVR-SpaceCalibratorDriver/IPCServer_win.cpp new file mode 100644 index 00000000..358252ac --- /dev/null +++ b/OpenVR-SpaceCalibratorDriver/IPCServer_win.cpp @@ -0,0 +1,247 @@ +#include "IPCServer.h" +#include "Logging.h" +#include "ServerTrackedDeviceProvider.h" + +struct IPCClientImpl{ + struct PipeInstance + { + OVERLAPPED overlap; // Used by the API + HANDLE pipe; + IPCServer *server; + + protocol::Request request; + protocol::Response response; + }; + + PipeInstance *CreatePipeInstance(HANDLE pipe); + void ClosePipeInstance(PipeInstance *pipeInst); + static void WINAPI CompletedReadCallback(DWORD err, DWORD bytesRead, LPOVERLAPPED overlap); + static void WINAPI CompletedWriteCallback(DWORD err, DWORD bytesWritten, LPOVERLAPPED overlap); + static BOOL CreateAndConnectInstance(LPOVERLAPPED overlap, HANDLE &pipe); + + std::set pipes; + HANDLE connectEvent; +}; + + +IPCServer::IPCServer(ServerTrackedDeviceProvider *driver); : driver(driver) +{ + impl = std::make_unique(); +} + +void IPCServer::HandleRequest(const protocol::Request &request, protocol::Response &response) +{ + switch (request.type) + { + case protocol::RequestHandshake: + response.type = protocol::ResponseHandshake; + response.protocol.version = protocol::Version; + break; + + case protocol::RequestSetDeviceTransform: + driver->SetDeviceTransform(request.setDeviceTransform); + response.type = protocol::ResponseSuccess; + break; + + default: + LOG("Invalid IPC request: %d", request.type); + break; + } +} + +IPCServer::~IPCServer() +{ + Stop(); +} + +void IPCServer::Run() +{ + mainThread = std::thread(RunThread, this); +} + +void IPCServer::Stop() +{ + TRACE("%s", "IPCServer::Stop()"); + if (!running) + return; + stop = true; + + SetEvent(connectEvent); + mainThread.join(); + running = false; + TRACE("IPCServer::Stop() finished"); +} +IPCServerImpl::PipeInstance *IPCServerImpl::CreatePipeInstance(HANDLE pipe) +{ + auto pipeInst = new PipeInstance; + pipeInst->pipe = pipe; + pipeInst->server = this; + pipes.insert(pipeInst); + return pipeInst; +} + +void IPCServerImpl::ClosePipeInstance(PipeInstance *pipeInst) +{ + DisconnectNamedPipe(pipeInst->pipe); + CloseHandle(pipeInst->pipe); + pipes.erase(pipeInst); + delete pipeInst; +} + +void IPCServer::RunThread(IPCServer *_this) +{ + _this->running = true; + LPTSTR pipeName = TEXT(OPENVR_SPACECALIBRATOR_PIPE_NAME); + + HANDLE connectEvent = _this->connectEvent = CreateEvent(0, TRUE, TRUE, 0); + if (!connectEvent) + { + LOG("CreateEvent failed in RunThread. Error: %d", GetLastError()); + return; + } + + OVERLAPPED connectOverlap; + connectOverlap.hEvent = connectEvent; + + HANDLE nextPipe; + BOOL connectPending = CreateAndConnectInstance(&connectOverlap, nextPipe); + + while (!_this->stop) + { + DWORD wait = WaitForSingleObjectEx(connectEvent, INFINITE, TRUE); + + if (_this->stop) + { + break; + } + else if (wait == 0) + { + // When connectPending is false, the last call to CreateAndConnectInstance + // picked up a connected client and triggered this event, so we can simply + // create a new pipe instance for it. If true, the client was still pending + // connection when CreateAndConnectInstance returned, so this event was triggered + // internally and we need to flush out the result, or something like that. + if (connectPending) + { + DWORD bytesConnect; + BOOL success = GetOverlappedResult(nextPipe, &connectOverlap, &bytesConnect, FALSE); + if (!success) + { + LOG("GetOverlappedResult failed in RunThread. Error: %d", GetLastError()); + return; + } + } + + LOG("IPC client connected"); + + auto pipeInst = _this->CreatePipeInstance(nextPipe); + CompletedWriteCallback(0, sizeof protocol::Response, (LPOVERLAPPED) pipeInst); + + connectPending = CreateAndConnectInstance(&connectOverlap, nextPipe); + } + else if (wait != WAIT_IO_COMPLETION) + { + printf("WaitForSingleObjectEx failed in RunThread. Error %d", GetLastError()); + return; + } + } + + for (auto &pipeInst : _this->pipes) + { + _this->impl->ClosePipeInstance(pipeInst); + } + _this->pipes.clear(); +} + +BOOL IPCServerImpl::CreateAndConnectInstance(LPOVERLAPPED overlap, HANDLE &pipe) +{ + + pipe = CreateNamedPipe( + TEXT(OPENVR_SPACECALIBRATOR_PIPE_NAME), + PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, + PIPE_UNLIMITED_INSTANCES, + sizeof protocol::Request, + sizeof protocol::Response, + 1000, + 0 + ); + + if (pipe == INVALID_HANDLE_VALUE) + { + LOG("CreateNamedPipe failed. Error: %d", GetLastError()); + return FALSE; + } + + ConnectNamedPipe(pipe, overlap); + + switch(GetLastError()) + { + case ERROR_IO_PENDING: + // Mark a pending connection by returning true, and when the connection + // completes an event will trigger automatically. + return TRUE; + + case ERROR_PIPE_CONNECTED: + // Signal the event loop that a client is connected. + if (SetEvent(overlap->hEvent)) + return FALSE; + } + + LOG("ConnectNamedPipe failed. Error: %d", GetLastError()); + return FALSE; +} + +void IPCServerImpl::CompletedReadCallback(DWORD err, DWORD bytesRead, LPOVERLAPPED overlap) +{ + PipeInstance *pipeInst = (PipeInstance *) overlap; + BOOL success = FALSE; + + if (err == 0 && bytesRead > 0) + { + pipeInst->server->HandleRequest(pipeInst->request, pipeInst->response); + success = WriteFileEx( + pipeInst->pipe, + &pipeInst->response, + sizeof protocol::Response, + overlap, + (LPOVERLAPPED_COMPLETION_ROUTINE) CompletedWriteCallback + ); + } + + if (!success) + { + if (err == ERROR_BROKEN_PIPE) + { + LOG("IPC client disconnecting normally"); + } + else + { + LOG("IPC client disconnecting due to error (via CompletedReadCallback), error: %d, bytesRead: %d", err, bytesRead); + } + pipeInst->server->ClosePipeInstance(pipeInst); + } +} + +void IPCServerImpl::CompletedWriteCallback(DWORD err, DWORD bytesWritten, LPOVERLAPPED overlap) +{ + PipeInstance *pipeInst = (PipeInstance *) overlap; + BOOL success = FALSE; + + if (err == 0 && bytesWritten == sizeof protocol::Response) + { + success = ReadFileEx( + pipeInst->pipe, + &pipeInst->request, + sizeof protocol::Request, + overlap, + (LPOVERLAPPED_COMPLETION_ROUTINE) CompletedReadCallback + ); + } + + if (!success) + { + LOG("IPC client disconnecting due to error (via CompletedWriteCallback), error: %d, bytesWritten: %d", err, bytesWritten); + pipeInst->server->ClosePipeInstance(pipeInst); + } +} From 67ec6b5ef60a6d2bafdc6b56ad76daa782ff7f2c Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Fri, 21 Oct 2022 20:59:41 -0500 Subject: [PATCH 23/27] Better .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 9e868919..dfb04e94 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,5 @@ ipch OpenVR-SpaceCalibratorDriver/01spacecalibrator/bin/linux64/ build *.gitignore +*.py +usr/ From dda44454e9dbee69f00b3a29394307d696dde808 Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Sat, 22 Oct 2022 20:12:56 -0500 Subject: [PATCH 24/27] Builds under linux again, now with much less preprocessor --- OpenVR-SpaceCalibrator/Configuration.h | 4 - OpenVR-SpaceCalibrator/IPCClient.cpp | 129 --------- OpenVR-SpaceCalibrator/IPCClient.h | 15 +- OpenVR-SpaceCalibrator/IPCClient_linux.cpp | 84 +----- OpenVR-SpaceCalibrator/targetver.h | 4 - OpenVR-SpaceCalibratorDriver/Hooking.h | 65 +++-- OpenVR-SpaceCalibratorDriver/IPCServer.cpp | 253 ------------------ OpenVR-SpaceCalibratorDriver/IPCServer.h | 31 +-- .../IPCServer_linux.cpp | 6 +- 9 files changed, 59 insertions(+), 532 deletions(-) delete mode 100644 OpenVR-SpaceCalibrator/IPCClient.cpp delete mode 100644 OpenVR-SpaceCalibratorDriver/IPCServer.cpp diff --git a/OpenVR-SpaceCalibrator/Configuration.h b/OpenVR-SpaceCalibrator/Configuration.h index 545bfba8..43623a46 100644 --- a/OpenVR-SpaceCalibrator/Configuration.h +++ b/OpenVR-SpaceCalibrator/Configuration.h @@ -2,9 +2,5 @@ #include "Calibration.h" -#ifdef __linux__ -#include "StaticConfig.h" -#endif - void LoadProfile(CalibrationContext &ctx); void SaveProfile(CalibrationContext &ctx); diff --git a/OpenVR-SpaceCalibrator/IPCClient.cpp b/OpenVR-SpaceCalibrator/IPCClient.cpp deleted file mode 100644 index f64fddf3..00000000 --- a/OpenVR-SpaceCalibrator/IPCClient.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include "IPCClient.h" -#ifdef __linux__ -#include "Comms.h" -#endif - -#include -#include - -#ifdef __linux__ -// NOP -#else -static std::string LastErrorString(DWORD lastError) -{ - LPSTR buffer = nullptr; - size_t size = FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, lastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, NULL - ); - - std::string message(buffer, size); - LocalFree(buffer); - return message; -} -#endif - -IPCClient::~IPCClient() -{ -#ifdef __linux__ - //NOP -#else - if (pipe && pipe != INVALID_HANDLE_VALUE) - CloseHandle(pipe); -#endif -} - -void IPCClient::Connect() -{ -#ifdef __linux__ -#else - LPTSTR pipeName = TEXT(OPENVR_SPACECALIBRATOR_PIPE_NAME); - - WaitNamedPipe(pipeName, 1000); - pipe = CreateFile(pipeName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); - - if (pipe == INVALID_HANDLE_VALUE) - { - throw std::runtime_error("Space Calibrator driver unavailable. Make sure SteamVR is running, and the Space Calibrator addon is enabled in SteamVR settings."); - } - - DWORD mode = PIPE_READMODE_MESSAGE; - if (!SetNamedPipeHandleState(pipe, &mode, 0, 0)) - { - throw std::runtime_error("Couldn't set pipe mode. Error: " + LastErrorString(GetLastError())); - } -#endif - auto response = SendBlocking(protocol::Request(protocol::RequestHandshake)); - if (response.type != protocol::ResponseHandshake || response.protocol.version != protocol::Version) - { - throw std::runtime_error( - "Incorrect driver version installed, try reinstalling OpenVR-SpaceCalibrator. (Client: " + - std::to_string(protocol::Version) + - ", Driver: " + - std::to_string(response.protocol.version) + - ")" - ); - } -} - -protocol::Response IPCClient::SendBlocking(const protocol::Request &request) -{ -#ifdef __linux__ - for(int i=0; i<10; i++){ - Send(request); - try{ - return Receive(); - } catch (std::runtime_error &t) { - LOG("%s: %s", "Recv timeout failed", t.what()); - } - } - throw std::runtime_error("Fell through read loop"); -#else - Send(request); - return Receive(); -#endif -} - -void IPCClient::Send(const protocol::Request &request) -{ -#ifdef __linux__ - pipe.Send(request); -#else - DWORD bytesWritten; - BOOL success = WriteFile(pipe, &request, sizeof request, &bytesWritten, 0); - if (!success) - { - throw std::runtime_error("Error writing IPC request. Error: " + LastErrorString(GetLastError())); - } -#endif -} - -protocol::Response IPCClient::Receive() -{ - protocol::Response response(protocol::ResponseInvalid); -#ifdef __linux__ - if( pipe.Recv(&response) ) - return response; - else - throw std::runtime_error("No packet was received"); -#else - DWORD bytesRead; - - BOOL success = ReadFile(pipe, &response, sizeof response, &bytesRead, 0); - if (!success) - { - DWORD lastError = GetLastError(); - if (lastError != ERROR_MORE_DATA) - { - throw std::runtime_error("Error reading IPC response. Error: " + LastErrorString(lastError)); - } - } - - if (bytesRead != sizeof response) - { - throw std::runtime_error("Invalid IPC response with size " + std::to_string(bytesRead)); - } - - return response; -#endif -} diff --git a/OpenVR-SpaceCalibrator/IPCClient.h b/OpenVR-SpaceCalibrator/IPCClient.h index 1044e4b5..81eebf44 100644 --- a/OpenVR-SpaceCalibrator/IPCClient.h +++ b/OpenVR-SpaceCalibrator/IPCClient.h @@ -1,16 +1,15 @@ #pragma once -#ifdef __linux__ -#include "Comms.h" -#else -#endif - +#include #include "../Protocol.h" +struct IPCClientImpl; + class IPCClient { public: ~IPCClient(); + IPCClient(); void Connect(); protocol::Response SendBlocking(const protocol::Request &request); @@ -19,9 +18,5 @@ class IPCClient protocol::Response Receive(); private: -#ifdef __linux__ - Client pipe; -#else - HANDLE pipe = INVALID_HANDLE_VALUE; -#endif + std::unique_ptr impl; }; diff --git a/OpenVR-SpaceCalibrator/IPCClient_linux.cpp b/OpenVR-SpaceCalibrator/IPCClient_linux.cpp index f64fddf3..c3551bfb 100644 --- a/OpenVR-SpaceCalibrator/IPCClient_linux.cpp +++ b/OpenVR-SpaceCalibrator/IPCClient_linux.cpp @@ -1,58 +1,25 @@ #include "IPCClient.h" -#ifdef __linux__ #include "Comms.h" -#endif #include #include -#ifdef __linux__ -// NOP -#else -static std::string LastErrorString(DWORD lastError) -{ - LPSTR buffer = nullptr; - size_t size = FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, lastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, NULL - ); +struct IPCClientImpl{ + Client pipe; +}; - std::string message(buffer, size); - LocalFree(buffer); - return message; +IPCClient::IPCClient() +{ + impl = std::make_unique(); } -#endif IPCClient::~IPCClient() { -#ifdef __linux__ //NOP -#else - if (pipe && pipe != INVALID_HANDLE_VALUE) - CloseHandle(pipe); -#endif } void IPCClient::Connect() { -#ifdef __linux__ -#else - LPTSTR pipeName = TEXT(OPENVR_SPACECALIBRATOR_PIPE_NAME); - - WaitNamedPipe(pipeName, 1000); - pipe = CreateFile(pipeName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); - - if (pipe == INVALID_HANDLE_VALUE) - { - throw std::runtime_error("Space Calibrator driver unavailable. Make sure SteamVR is running, and the Space Calibrator addon is enabled in SteamVR settings."); - } - - DWORD mode = PIPE_READMODE_MESSAGE; - if (!SetNamedPipeHandleState(pipe, &mode, 0, 0)) - { - throw std::runtime_error("Couldn't set pipe mode. Error: " + LastErrorString(GetLastError())); - } -#endif auto response = SendBlocking(protocol::Request(protocol::RequestHandshake)); if (response.type != protocol::ResponseHandshake || response.protocol.version != protocol::Version) { @@ -68,7 +35,6 @@ void IPCClient::Connect() protocol::Response IPCClient::SendBlocking(const protocol::Request &request) { -#ifdef __linux__ for(int i=0; i<10; i++){ Send(request); try{ @@ -78,52 +44,18 @@ protocol::Response IPCClient::SendBlocking(const protocol::Request &request) } } throw std::runtime_error("Fell through read loop"); -#else - Send(request); - return Receive(); -#endif } void IPCClient::Send(const protocol::Request &request) { -#ifdef __linux__ - pipe.Send(request); -#else - DWORD bytesWritten; - BOOL success = WriteFile(pipe, &request, sizeof request, &bytesWritten, 0); - if (!success) - { - throw std::runtime_error("Error writing IPC request. Error: " + LastErrorString(GetLastError())); - } -#endif + impl->pipe.Send(request); } protocol::Response IPCClient::Receive() { protocol::Response response(protocol::ResponseInvalid); -#ifdef __linux__ - if( pipe.Recv(&response) ) + if( impl->pipe.Recv(&response) ) return response; else throw std::runtime_error("No packet was received"); -#else - DWORD bytesRead; - - BOOL success = ReadFile(pipe, &response, sizeof response, &bytesRead, 0); - if (!success) - { - DWORD lastError = GetLastError(); - if (lastError != ERROR_MORE_DATA) - { - throw std::runtime_error("Error reading IPC response. Error: " + LastErrorString(lastError)); - } - } - - if (bytesRead != sizeof response) - { - throw std::runtime_error("Invalid IPC response with size " + std::to_string(bytesRead)); - } - - return response; -#endif } diff --git a/OpenVR-SpaceCalibrator/targetver.h b/OpenVR-SpaceCalibrator/targetver.h index 0b7e2338..adb81acb 100644 --- a/OpenVR-SpaceCalibrator/targetver.h +++ b/OpenVR-SpaceCalibrator/targetver.h @@ -4,8 +4,4 @@ // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. -#ifdef __linux__ -// NOP: not in linux build -#else #include -#endif diff --git a/OpenVR-SpaceCalibratorDriver/Hooking.h b/OpenVR-SpaceCalibratorDriver/Hooking.h index 1c9a5d63..cfc04188 100644 --- a/OpenVR-SpaceCalibratorDriver/Hooking.h +++ b/OpenVR-SpaceCalibratorDriver/Hooking.h @@ -10,9 +10,10 @@ #include #endif - -#include #include +#include +#include +#include class IHook { @@ -35,44 +36,59 @@ class IHook template class Hook : public IHook { + void * obj = nullptr; + int offset = 0; public: FuncType originalFunc = nullptr; Hook(const std::string &name) : IHook(name) { } #ifdef __linux__ - template + template bool CreateHookInObjectVTable(void *object, int vtableOffset, T* detourFunction) { + long pageSize = sysconf(_SC_PAGESIZE); + + obj = object; + offset = vtableOffset; // For virtual objects, VC++ (and from what I can tell gcc) adds a pointer to the vtable as the first member. // To access the vtable, we simply dereference the object. void **vtable = *((void ***)object); // The vtable itself is an array of pointers to member functions, // in the order they were declared in. - originalFunc = (FuncType) vtable[vtableOffset]; - targetFunc = (void*) vtable[vtableOffset]; - - uintptr_t otherPage = (uintptr_t) vtable & ~(uintptr_t) 4095; - int err = mprotect((void*) otherPage, 8196, PROT_READ | PROT_WRITE); - if(err){ - LOG("Failed to set memory protection %d-%s", err, strerror(errno)); - } - else { - //LOG("%s", "Setting vtable value"); - vtable[vtableOffset] = (void*) detourFunction; - //LOG("%s", "Resetting permissions vtable value"); - mprotect((void*) otherPage, 8196, PROT_READ | PROT_EXEC); - } + originalFunc = (FuncType) vtable[vtableOffset]; + targetFunc = (void*) vtable[vtableOffset]; + if((uintptr_t) vtable % 8 != 0 ) + { + obj = nullptr; + originalFunc = nullptr; + throw std::runtime_error("vtable entry not aligned to 8 byte pointer"); + } + + uintptr_t otherPage = (uintptr_t) vtable & ~(uintptr_t) (pageSize - 1); + int err = mprotect((void*) otherPage, pageSize, PROT_READ | PROT_WRITE); + if(err){ + LOG("Failed to set memory protection %d-%s", err, strerror(errno)); + } + else { + //LOG("%s", "Setting vtable value"); + vtable[vtableOffset] = (void*) detourFunction; + //LOG("%s", "Resetting permissions vtable value"); + mprotect((void*) otherPage, pageSize, PROT_READ | PROT_EXEC); + } LOG("Enabled Linux hook for %s", name.c_str()); enabled = true; return true; } #else - template + template bool CreateHookInObjectVTable(void *object, int vtableOffset, T* detourFunction) { + obj = object; + offset = vtableOffset; + // For virtual objects, VC++ (and from what I can tell gcc) adds a pointer to the vtable as the first member. // To access the vtable, we simply dereference the object. void **vtable = *((void ***)object); @@ -102,18 +118,25 @@ template class Hook : public IHook } #endif +#ifdef __linux__ void Destroy() { -#ifdef __linux__ - // should probably do something, but meh. + //redoing it is enough if it was done the first time. + if(obj && originalFunc) CreateHookInObjectVTable(obj, offset, originalFunc); + obj = nullptr; + originalFunc = nullptr; + } #else + + void Destroy() + { if (enabled) { MH_RemoveHook(targetFunc); enabled = false; } -#endif } +#endif private: bool enabled = false; diff --git a/OpenVR-SpaceCalibratorDriver/IPCServer.cpp b/OpenVR-SpaceCalibratorDriver/IPCServer.cpp deleted file mode 100644 index ebed1269..00000000 --- a/OpenVR-SpaceCalibratorDriver/IPCServer.cpp +++ /dev/null @@ -1,253 +0,0 @@ -#include "IPCServer.h" -#include "Logging.h" -#include "ServerTrackedDeviceProvider.h" - -#ifdef __linux__ -#include "Comms.h" -#else - -#endif - - -void IPCServer::HandleRequest(const protocol::Request &request, protocol::Response &response) -{ - switch (request.type) - { - case protocol::RequestHandshake: - response.type = protocol::ResponseHandshake; - response.protocol.version = protocol::Version; - break; - - case protocol::RequestSetDeviceTransform: - driver->SetDeviceTransform(request.setDeviceTransform); - response.type = protocol::ResponseSuccess; - break; - - default: - LOG("Invalid IPC request: %d", request.type); - break; - } -} - -IPCServer::~IPCServer() -{ - Stop(); -} - -void IPCServer::Run() -{ - mainThread = std::thread(RunThread, this); -} - -void IPCServer::Stop() -{ - TRACE("%s", "IPCServer::Stop()"); - if (!running) - return; - stop = true; - -#ifdef __linux__ - //NOP -#else - SetEvent(connectEvent); - mainThread.join(); - running = false; - TRACE("IPCServer::Stop() finished"); -#endif -} -#ifdef __linux__ - //NOP -#else -IPCServer::PipeInstance *IPCServer::CreatePipeInstance(HANDLE pipe) -{ - auto pipeInst = new PipeInstance; - pipeInst->pipe = pipe; - pipeInst->server = this; - pipes.insert(pipeInst); - return pipeInst; -} - -void IPCServer::ClosePipeInstance(PipeInstance *pipeInst) -{ - DisconnectNamedPipe(pipeInst->pipe); - CloseHandle(pipeInst->pipe); - pipes.erase(pipeInst); - delete pipeInst; -} -#endif - -void IPCServer::RunThread(IPCServer *_this) -{ -#ifdef __linux__ - Comms comms; - - protocol::Response response; - protocol::Request request; - - while(!_this->stop){ - comms.Recv(&request); - _this->HandleRequest(request, response); - comms.Send(response); - } - LOG("%s", "Stop requested"); -#else - _this->running = true; - LPTSTR pipeName = TEXT(OPENVR_SPACECALIBRATOR_PIPE_NAME); - - HANDLE connectEvent = _this->connectEvent = CreateEvent(0, TRUE, TRUE, 0); - if (!connectEvent) - { - LOG("CreateEvent failed in RunThread. Error: %d", GetLastError()); - return; - } - - OVERLAPPED connectOverlap; - connectOverlap.hEvent = connectEvent; - - HANDLE nextPipe; - BOOL connectPending = CreateAndConnectInstance(&connectOverlap, nextPipe); - - while (!_this->stop) - { - DWORD wait = WaitForSingleObjectEx(connectEvent, INFINITE, TRUE); - - if (_this->stop) - { - break; - } - else if (wait == 0) - { - // When connectPending is false, the last call to CreateAndConnectInstance - // picked up a connected client and triggered this event, so we can simply - // create a new pipe instance for it. If true, the client was still pending - // connection when CreateAndConnectInstance returned, so this event was triggered - // internally and we need to flush out the result, or something like that. - if (connectPending) - { - DWORD bytesConnect; - BOOL success = GetOverlappedResult(nextPipe, &connectOverlap, &bytesConnect, FALSE); - if (!success) - { - LOG("GetOverlappedResult failed in RunThread. Error: %d", GetLastError()); - return; - } - } - - LOG("IPC client connected"); - - auto pipeInst = _this->CreatePipeInstance(nextPipe); - CompletedWriteCallback(0, sizeof protocol::Response, (LPOVERLAPPED) pipeInst); - - connectPending = CreateAndConnectInstance(&connectOverlap, nextPipe); - } - else if (wait != WAIT_IO_COMPLETION) - { - printf("WaitForSingleObjectEx failed in RunThread. Error %d", GetLastError()); - return; - } - } - - for (auto &pipeInst : _this->pipes) - { - _this->ClosePipeInstance(pipeInst); - } - _this->pipes.clear(); -#endif -} - -#ifdef __linux__ -//NOP -#else -BOOL IPCServer::CreateAndConnectInstance(LPOVERLAPPED overlap, HANDLE &pipe) -{ - - pipe = CreateNamedPipe( - TEXT(OPENVR_SPACECALIBRATOR_PIPE_NAME), - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, - sizeof protocol::Request, - sizeof protocol::Response, - 1000, - 0 - ); - - if (pipe == INVALID_HANDLE_VALUE) - { - LOG("CreateNamedPipe failed. Error: %d", GetLastError()); - return FALSE; - } - - ConnectNamedPipe(pipe, overlap); - - switch(GetLastError()) - { - case ERROR_IO_PENDING: - // Mark a pending connection by returning true, and when the connection - // completes an event will trigger automatically. - return TRUE; - - case ERROR_PIPE_CONNECTED: - // Signal the event loop that a client is connected. - if (SetEvent(overlap->hEvent)) - return FALSE; - } - - LOG("ConnectNamedPipe failed. Error: %d", GetLastError()); - return FALSE; -} - -void IPCServer::CompletedReadCallback(DWORD err, DWORD bytesRead, LPOVERLAPPED overlap) -{ - PipeInstance *pipeInst = (PipeInstance *) overlap; - BOOL success = FALSE; - - if (err == 0 && bytesRead > 0) - { - pipeInst->server->HandleRequest(pipeInst->request, pipeInst->response); - success = WriteFileEx( - pipeInst->pipe, - &pipeInst->response, - sizeof protocol::Response, - overlap, - (LPOVERLAPPED_COMPLETION_ROUTINE) CompletedWriteCallback - ); - } - - if (!success) - { - if (err == ERROR_BROKEN_PIPE) - { - LOG("IPC client disconnecting normally"); - } - else - { - LOG("IPC client disconnecting due to error (via CompletedReadCallback), error: %d, bytesRead: %d", err, bytesRead); - } - pipeInst->server->ClosePipeInstance(pipeInst); - } -} - -void IPCServer::CompletedWriteCallback(DWORD err, DWORD bytesWritten, LPOVERLAPPED overlap) -{ - PipeInstance *pipeInst = (PipeInstance *) overlap; - BOOL success = FALSE; - - if (err == 0 && bytesWritten == sizeof protocol::Response) - { - success = ReadFileEx( - pipeInst->pipe, - &pipeInst->request, - sizeof protocol::Request, - overlap, - (LPOVERLAPPED_COMPLETION_ROUTINE) CompletedReadCallback - ); - } - - if (!success) - { - LOG("IPC client disconnecting due to error (via CompletedWriteCallback), error: %d, bytesWritten: %d", err, bytesWritten); - pipeInst->server->ClosePipeInstance(pipeInst); - } -} -#endif diff --git a/OpenVR-SpaceCalibratorDriver/IPCServer.h b/OpenVR-SpaceCalibratorDriver/IPCServer.h index 924f1d0d..42217593 100644 --- a/OpenVR-SpaceCalibratorDriver/IPCServer.h +++ b/OpenVR-SpaceCalibratorDriver/IPCServer.h @@ -6,19 +6,12 @@ #include #include -#ifdef __linux__ -//NOP: linux isn't windows -#else -#define WIN32_LEAN_AND_MEAN -#include -#endif - class ServerTrackedDeviceProvider; class IPCServer { public: - IPCServer(ServerTrackedDeviceProvider *driver) : driver(driver) { } + IPCServer(ServerTrackedDeviceProvider *driver); ~IPCServer(); void Run(); @@ -27,28 +20,6 @@ class IPCServer private: void HandleRequest(const protocol::Request &request, protocol::Response &response); -#ifdef __linux__ - //NOP: Not used in Linux build -#else - struct PipeInstance - { - OVERLAPPED overlap; // Used by the API - HANDLE pipe; - IPCServer *server; - - protocol::Request request; - protocol::Response response; - }; - - PipeInstance *CreatePipeInstance(HANDLE pipe); - void ClosePipeInstance(PipeInstance *pipeInst); - static void WINAPI CompletedReadCallback(DWORD err, DWORD bytesRead, LPOVERLAPPED overlap); - static void WINAPI CompletedWriteCallback(DWORD err, DWORD bytesWritten, LPOVERLAPPED overlap); - static BOOL CreateAndConnectInstance(LPOVERLAPPED overlap, HANDLE &pipe); - - std::set pipes; - HANDLE connectEvent; -#endif static void RunThread(IPCServer *_this); std::thread mainThread; diff --git a/OpenVR-SpaceCalibratorDriver/IPCServer_linux.cpp b/OpenVR-SpaceCalibratorDriver/IPCServer_linux.cpp index f61a5cfe..0c980658 100644 --- a/OpenVR-SpaceCalibratorDriver/IPCServer_linux.cpp +++ b/OpenVR-SpaceCalibratorDriver/IPCServer_linux.cpp @@ -3,11 +3,6 @@ #include "ServerTrackedDeviceProvider.h" #include "Comms.h" -#include "" - -struct IPCServerImpl { -}; - void IPCServer::HandleRequest(const protocol::Request &request, protocol::Response &response) { switch (request.type) @@ -45,6 +40,7 @@ void IPCServer::Stop() return; stop = true; } + void IPCServer::RunThread(IPCServer *_this) { Comms comms; From c1511a383e8d7598b67bcdae84172a9e1c515b30 Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Sat, 22 Oct 2022 20:50:08 -0500 Subject: [PATCH 25/27] Add executable to memory permissions when writing hook --- OpenVR-SpaceCalibratorDriver/Hooking.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenVR-SpaceCalibratorDriver/Hooking.h b/OpenVR-SpaceCalibratorDriver/Hooking.h index cfc04188..672b6e46 100644 --- a/OpenVR-SpaceCalibratorDriver/Hooking.h +++ b/OpenVR-SpaceCalibratorDriver/Hooking.h @@ -67,7 +67,7 @@ template class Hook : public IHook } uintptr_t otherPage = (uintptr_t) vtable & ~(uintptr_t) (pageSize - 1); - int err = mprotect((void*) otherPage, pageSize, PROT_READ | PROT_WRITE); + int err = mprotect((void*) otherPage, pageSize, PROT_READ | PROT_WRITE | PROT_EXEC); if(err){ LOG("Failed to set memory protection %d-%s", err, strerror(errno)); } From e5b0baee118afd0db7344552923dc1e81ebada3b Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Sat, 22 Oct 2022 20:54:31 -0500 Subject: [PATCH 26/27] Reverting logging change --- OpenVR-SpaceCalibratorDriver/Logging.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenVR-SpaceCalibratorDriver/Logging.h b/OpenVR-SpaceCalibratorDriver/Logging.h index 88ce0a0b..5ecb9ded 100644 --- a/OpenVR-SpaceCalibratorDriver/Logging.h +++ b/OpenVR-SpaceCalibratorDriver/Logging.h @@ -17,7 +17,7 @@ void LogFlush(); } while (0) #endif -//#define TRACE(...) {} +#define TRACE(...) {} #ifndef TRACE #define TRACE LOG From a4151fccdad6cbea25eefe1810505ccc61a63aae Mon Sep 17 00:00:00 2001 From: AngriestSCV Date: Sat, 22 Oct 2022 21:04:36 -0500 Subject: [PATCH 27/27] Replacing spaces with tabs --- OpenVR-SpaceCalibrator/HandleCommandLine.h | 6 +- OpenVR-SpaceCalibrator/IPCClient_linux.cpp | 28 +- OpenVR-SpaceCalibrator/UserInterface.cpp | 14 +- OpenVR-SpaceCalibrator/main_linux.cpp | 90 +++---- OpenVR-SpaceCalibratorDriver/Comms.h | 240 +++++++++--------- .../IPCServer_linux.cpp | 20 +- .../InterfaceHookInjector.cpp | 4 +- OpenVR-SpaceCalibratorDriver/Logging.cpp | 6 +- .../ServerTrackedDeviceProvider.cpp | 4 +- OpenVR-SpaceCalibratorDriver/dllmain.cpp | 8 +- 10 files changed, 211 insertions(+), 209 deletions(-) diff --git a/OpenVR-SpaceCalibrator/HandleCommandLine.h b/OpenVR-SpaceCalibrator/HandleCommandLine.h index d23b0ad4..af8b55d9 100644 --- a/OpenVR-SpaceCalibrator/HandleCommandLine.h +++ b/OpenVR-SpaceCalibrator/HandleCommandLine.h @@ -51,7 +51,7 @@ static inline void InstallManifest(char const * const cwd, int max_path) { } } std::string manifestPath = cwd; - manifestPath = HandleCommandLine::ManifestPath(manifestPath); + manifestPath = HandleCommandLine::ManifestPath(manifestPath); std::cout << "Adding manifest path: " << manifestPath << std::endl; auto vrAppErr = vr::VRApplications()->AddApplicationManifest(manifestPath.c_str()); @@ -78,8 +78,8 @@ static inline void RemoveManifest(char const * const cwd) { { if (vr::VRApplications()->IsApplicationInstalled(OPENVR_APPLICATION_KEY)) { - std::string manifestPath = cwd; - manifestPath = ManifestPath(manifestPath); + std::string manifestPath = cwd; + manifestPath = ManifestPath(manifestPath); std::cout << "Removing manifest path: " << manifestPath << std::endl; vr::VRApplications()->RemoveApplicationManifest(manifestPath.c_str()); diff --git a/OpenVR-SpaceCalibrator/IPCClient_linux.cpp b/OpenVR-SpaceCalibrator/IPCClient_linux.cpp index c3551bfb..8ec39acf 100644 --- a/OpenVR-SpaceCalibrator/IPCClient_linux.cpp +++ b/OpenVR-SpaceCalibrator/IPCClient_linux.cpp @@ -15,7 +15,7 @@ IPCClient::IPCClient() IPCClient::~IPCClient() { - //NOP + //NOP } void IPCClient::Connect() @@ -35,27 +35,27 @@ void IPCClient::Connect() protocol::Response IPCClient::SendBlocking(const protocol::Request &request) { - for(int i=0; i<10; i++){ - Send(request); - try{ - return Receive(); - } catch (std::runtime_error &t) { - LOG("%s: %s", "Recv timeout failed", t.what()); - } - } - throw std::runtime_error("Fell through read loop"); + for(int i=0; i<10; i++){ + Send(request); + try{ + return Receive(); + } catch (std::runtime_error &t) { + LOG("%s: %s", "Recv timeout failed", t.what()); + } + } + throw std::runtime_error("Fell through read loop"); } void IPCClient::Send(const protocol::Request &request) { - impl->pipe.Send(request); + impl->pipe.Send(request); } protocol::Response IPCClient::Receive() { protocol::Response response(protocol::ResponseInvalid); - if( impl->pipe.Recv(&response) ) - return response; - else + if( impl->pipe.Recv(&response) ) + return response; + else throw std::runtime_error("No packet was received"); } diff --git a/OpenVR-SpaceCalibrator/UserInterface.cpp b/OpenVR-SpaceCalibrator/UserInterface.cpp index 8a2df673..c83b53a3 100644 --- a/OpenVR-SpaceCalibrator/UserInterface.cpp +++ b/OpenVR-SpaceCalibrator/UserInterface.cpp @@ -73,7 +73,7 @@ void BuildMenu(bool runningInOverlay) if (CalCtx.validProfile && !CalCtx.enabled) { ImGui::TextColored(ImColor(0.8f, 0.2f, 0.2f), "Reference (%s) HMD not detected, profile disabled", CalCtx.referenceTrackingSystem.c_str()); - ImGui::Text("%s", ""); + ImGui::Text("%s", ""); } float width = ImGui::GetWindowContentRegionWidth(), scale = 1.0f; @@ -113,7 +113,7 @@ void BuildMenu(bool runningInOverlay) scale = 0.5; } - ImGui::Text("%s", ""); + ImGui::Text("%s", ""); if (ImGui::Button("Copy Chaperone Bounds to profile", ImVec2(width * scale, ImGui::GetTextLineHeight() * 2))) { LoadChaperoneBounds(); @@ -134,22 +134,22 @@ void BuildMenu(bool runningInOverlay) } } - ImGui::Text("%s", ""); + ImGui::Text("%s", ""); auto speed = CalCtx.calibrationSpeed; ImGui::Columns(4, NULL, false); ImGui::Text("Calibration Speed"); ImGui::NextColumn(); - if (ImGui::RadioButton(" Fast ", speed == CalibrationContext::FAST)) + if (ImGui::RadioButton(" Fast ", speed == CalibrationContext::FAST)) CalCtx.calibrationSpeed = CalibrationContext::FAST; ImGui::NextColumn(); - if (ImGui::RadioButton(" Slow ", speed == CalibrationContext::SLOW)) + if (ImGui::RadioButton(" Slow ", speed == CalibrationContext::SLOW)) CalCtx.calibrationSpeed = CalibrationContext::SLOW; ImGui::NextColumn(); - if (ImGui::RadioButton(" Very Slow ", speed == CalibrationContext::VERY_SLOW)) + if (ImGui::RadioButton(" Very Slow ", speed == CalibrationContext::VERY_SLOW)) CalCtx.calibrationSpeed = CalibrationContext::VERY_SLOW; ImGui::Columns(1); @@ -204,7 +204,7 @@ void BuildMenu(bool runningInOverlay) if (CalCtx.state == CalibrationState::None) { - ImGui::Text("%s", ""); + ImGui::Text("%s", ""); if (ImGui::Button("Close", ImVec2(ImGui::GetWindowContentRegionWidth(), ImGui::GetTextLineHeight() * 2))) ImGui::CloseCurrentPopup(); } diff --git a/OpenVR-SpaceCalibrator/main_linux.cpp b/OpenVR-SpaceCalibrator/main_linux.cpp index 6f7aecc0..931b6eb7 100644 --- a/OpenVR-SpaceCalibrator/main_linux.cpp +++ b/OpenVR-SpaceCalibrator/main_linux.cpp @@ -32,16 +32,16 @@ int main(int argc, char ** argv) { const int max_path = 2048; char cwd[max_path] = {0}; - char const * cmdLine; - std::string str; - for(int i=1; i(max_path); - unsigned int pathLen; - vr::VR_GetRuntimePath(cruntimePath.get(), max_path, &pathLen); + unsigned int pathLen; + vr::VR_GetRuntimePath(cruntimePath.get(), max_path, &pathLen); - const int cmdLength = 8196; - char cmd[cmdLength]; + const int cmdLength = 8196; + char cmd[cmdLength]; - snprintf(cmd, cmdLength, "python " DRIVER_INSTALLER_PATH "/driverInstall.py --toInstall " DRIVER_MANIFEST_PATH " --vrpathreg %s/bin/vrpathreg.sh", cruntimePath.get()); - printf("cmd: %s\n", cmd); - system(cmd); + snprintf(cmd, cmdLength, "python " DRIVER_INSTALLER_PATH "/driverInstall.py --toInstall " DRIVER_MANIFEST_PATH " --vrpathreg %s/bin/vrpathreg.sh", cruntimePath.get()); + printf("cmd: %s\n", cmd); + system(cmd); - vr::VR_Shutdown(); - exit(0); + vr::VR_Shutdown(); + exit(0); } void UninstallDriver(int max_path){ @@ -78,41 +78,41 @@ void UninstallDriver(int max_path){ vr::VR_Init(&vrErr, vr::VRApplication_Utility); if (vrErr != vr::VRInitError_None) { - fprintf(stderr, "Failed to initialize OpenVR: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(vrErr)); - vr::VR_Shutdown(); - exit(-2); - } + fprintf(stderr, "Failed to initialize OpenVR: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(vrErr)); + vr::VR_Shutdown(); + exit(-2); + } auto cruntimePath = std::make_unique(max_path); - unsigned int pathLen; - vr::VR_GetRuntimePath(cruntimePath.get(), max_path, &pathLen); + unsigned int pathLen; + vr::VR_GetRuntimePath(cruntimePath.get(), max_path, &pathLen); - const int cmdLength = 8196; - char cmd[cmdLength]; + const int cmdLength = 8196; + char cmd[cmdLength]; - snprintf(cmd, cmdLength, "\"%s/bin/vrpathreg.sh\" removedriverwithname 01spacecalibrator", cruntimePath.get()); - printf("cmd: %s\n", cmd); + snprintf(cmd, cmdLength, "\"%s/bin/vrpathreg.sh\" removedriverwithname 01spacecalibrator", cruntimePath.get()); + printf("cmd: %s\n", cmd); - vr::VR_Shutdown(); - exit(0); + vr::VR_Shutdown(); + exit(0); } static void HandleCommandLineFunction(char const * cmdLine, char * cwd) { const int max_path = 2048; if (!strcmp(cmdLine, "-help") || !strcmp(cmdLine, "-h")) - { - std::cout << "usage - OpenVR SpaceCalibrator, only pick one option" << std::endl; - std::cout << "-openvrpath print runtime path of openvr" << std::endl; - std::cout << "-installmanifest install the application vrmanifest" << std::endl; - std::cout << "-removemanifest remove the application vrmanifest" << std::endl; - std::cout << "-activatemultipledrivers enable multiple drivers in steamvr" << std::endl; + { + std::cout << "usage - OpenVR SpaceCalibrator, only pick one option" << std::endl; + std::cout << "-openvrpath print runtime path of openvr" << std::endl; + std::cout << "-installmanifest install the application vrmanifest" << std::endl; + std::cout << "-removemanifest remove the application vrmanifest" << std::endl; + std::cout << "-activatemultipledrivers enable multiple drivers in steamvr" << std::endl; //Note that the next 2 are not on the windows build - std::cout << "-installdriver install the steam vr driver." << std::endl; - std::cout << "-uninstalldriver uninstall the steam vr driver." << std::endl; - std::cout << "-help -h print this message" << std::endl; - exit(0); - } + std::cout << "-installdriver install the steam vr driver." << std::endl; + std::cout << "-uninstalldriver uninstall the steam vr driver." << std::endl; + std::cout << "-help -h print this message" << std::endl; + exit(0); + } else if (!strcmp(cmdLine, "-openvrpath")) { char cruntimePath[max_path] = { 0 }; diff --git a/OpenVR-SpaceCalibratorDriver/Comms.h b/OpenVR-SpaceCalibratorDriver/Comms.h index 17c5ac28..163da394 100644 --- a/OpenVR-SpaceCalibratorDriver/Comms.h +++ b/OpenVR-SpaceCalibratorDriver/Comms.h @@ -15,134 +15,134 @@ #include "../Protocol.h" class UDPServerSocket{ - int sock; - public: - UDPServerSocket(const UDPServerSocket& other) = delete; - UDPServerSocket& operator=(const UDPServerSocket& other) = delete; - - UDPServerSocket(){} - - - bool Open(unsigned short port, int timeout=0){ - sockaddr_in my_addr = {}; - - my_addr.sin_family = AF_INET; - my_addr.sin_port = htons(port); - my_addr.sin_addr.s_addr = htonl(INADDR_ANY); - - //TODO verify that 0 is valid for UDP. - sock = socket(AF_INET, SOCK_DGRAM, 0); - - if(sock == -1){ - LOG("Failed to create socket: %s", strerror(errno)); - return false; - } - - - if(timeout > 0){ - struct timeval tv; - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof(tv)); - } - - int err = bind(sock, (sockaddr*)&my_addr, sizeof(my_addr)); - if(err){ - LOG("Failed to bind socket: %s", strerror(errno)); - return false; - } - return true; - } - - template - bool Recv(RecvObj* obj, sockaddr* client, socklen_t* clientSize) { - size_t targetSize = sizeof(*obj); - size_t bytes = recvfrom(sock, (void*)obj, targetSize, 0, - client, clientSize); - if(bytes != targetSize){ - LOG("Error, recieved %d bytes when %d were expected", bytes, (int)targetSize); - return false; - } - else { - return true; - } - } - - template - bool Send(const SendObj& obj, sockaddr* sendTo, size_t sendToSize) { - ssize_t targetSize = sizeof(obj); - ssize_t bytes = sendto(sock, (void*)&obj, targetSize, 0, sendTo, sendToSize); - return targetSize == bytes; - } + int sock; + public: + UDPServerSocket(const UDPServerSocket& other) = delete; + UDPServerSocket& operator=(const UDPServerSocket& other) = delete; + + UDPServerSocket(){} + + + bool Open(unsigned short port, int timeout=0){ + sockaddr_in my_addr = {}; + + my_addr.sin_family = AF_INET; + my_addr.sin_port = htons(port); + my_addr.sin_addr.s_addr = htonl(INADDR_ANY); + + //TODO verify that 0 is valid for UDP. + sock = socket(AF_INET, SOCK_DGRAM, 0); + + if(sock == -1){ + LOG("Failed to create socket: %s", strerror(errno)); + return false; + } + + + if(timeout > 0){ + struct timeval tv; + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof(tv)); + } + + int err = bind(sock, (sockaddr*)&my_addr, sizeof(my_addr)); + if(err){ + LOG("Failed to bind socket: %s", strerror(errno)); + return false; + } + return true; + } + + template + bool Recv(RecvObj* obj, sockaddr* client, socklen_t* clientSize) { + size_t targetSize = sizeof(*obj); + size_t bytes = recvfrom(sock, (void*)obj, targetSize, 0, + client, clientSize); + if(bytes != targetSize){ + LOG("Error, recieved %d bytes when %d were expected", bytes, (int)targetSize); + return false; + } + else { + return true; + } + } + + template + bool Send(const SendObj& obj, sockaddr* sendTo, size_t sendToSize) { + ssize_t targetSize = sizeof(obj); + ssize_t bytes = sendto(sock, (void*)&obj, targetSize, 0, sendTo, sendToSize); + return targetSize == bytes; + } }; template class Comms{ - sockaddr_in lastClient; - socklen_t peer_addr_len; - - UDPServerSocket sock; - public: - Comms(const Comms& other) = delete; - Comms& operator=(const Comms& other) = delete; - - Comms(){ - if( !sock.Open(COMM_PORT_SERVER) ){ - LOG("%s", "Error opening server socket"); - } - } - - void Recv(RecvObj* obj){ - if(sock.Recv(obj, (sockaddr*) &lastClient, &peer_addr_len)){ - return; - } else { - LOG("%s", "failed to recve value"); - return; - } - } - - void Send(const SendObj& obj ) { - sock.Send(obj, (sockaddr*) &lastClient, sizeof(lastClient)); - } + sockaddr_in lastClient; + socklen_t peer_addr_len; + + UDPServerSocket sock; + public: + Comms(const Comms& other) = delete; + Comms& operator=(const Comms& other) = delete; + + Comms(){ + if( !sock.Open(COMM_PORT_SERVER) ){ + LOG("%s", "Error opening server socket"); + } + } + + void Recv(RecvObj* obj){ + if(sock.Recv(obj, (sockaddr*) &lastClient, &peer_addr_len)){ + return; + } else { + LOG("%s", "failed to recve value"); + return; + } + } + + void Send(const SendObj& obj ) { + sock.Send(obj, (sockaddr*) &lastClient, sizeof(lastClient)); + } }; template class Client{ - sockaddr_in serverAddr = {}; - socklen_t peer_addr_len = {}; - - UDPServerSocket sock; - public: - Client(const Client& other) = delete; - Client& operator=(const Client& other) = delete; - - Client(){ - if( !sock.Open(COMM_PORT_CLIENT, 1000) ){ - LOG("%s", "Error opening server socket"); - } - - serverAddr.sin_family = AF_INET; - serverAddr.sin_port = htons(COMM_PORT_SERVER); - serverAddr.sin_addr.s_addr = INADDR_ANY; - } - - bool Recv(RecvObj* obj){ - sockaddr_in lastClient; - lastClient.sin_family = AF_INET; - lastClient.sin_port = htons(COMM_PORT_SERVER); - lastClient.sin_addr.s_addr = INADDR_ANY; - - if(sock.Recv(obj, (sockaddr*) &lastClient, &peer_addr_len)){ - return true; - } else { - LOG("%s", "failed to recve value"); - return false; - } - } - - void Send(const SendObj& obj ) { - sock.Send(obj, (sockaddr*) &serverAddr, sizeof(serverAddr)); - } + sockaddr_in serverAddr = {}; + socklen_t peer_addr_len = {}; + + UDPServerSocket sock; + public: + Client(const Client& other) = delete; + Client& operator=(const Client& other) = delete; + + Client(){ + if( !sock.Open(COMM_PORT_CLIENT, 1000) ){ + LOG("%s", "Error opening server socket"); + } + + serverAddr.sin_family = AF_INET; + serverAddr.sin_port = htons(COMM_PORT_SERVER); + serverAddr.sin_addr.s_addr = INADDR_ANY; + } + + bool Recv(RecvObj* obj){ + sockaddr_in lastClient; + lastClient.sin_family = AF_INET; + lastClient.sin_port = htons(COMM_PORT_SERVER); + lastClient.sin_addr.s_addr = INADDR_ANY; + + if(sock.Recv(obj, (sockaddr*) &lastClient, &peer_addr_len)){ + return true; + } else { + LOG("%s", "failed to recve value"); + return false; + } + } + + void Send(const SendObj& obj ) { + sock.Send(obj, (sockaddr*) &serverAddr, sizeof(serverAddr)); + } }; diff --git a/OpenVR-SpaceCalibratorDriver/IPCServer_linux.cpp b/OpenVR-SpaceCalibratorDriver/IPCServer_linux.cpp index 0c980658..7dfe6826 100644 --- a/OpenVR-SpaceCalibratorDriver/IPCServer_linux.cpp +++ b/OpenVR-SpaceCalibratorDriver/IPCServer_linux.cpp @@ -38,21 +38,23 @@ void IPCServer::Stop() TRACE("%s", "IPCServer::Stop()"); if (!running) return; + + stop = true; } void IPCServer::RunThread(IPCServer *_this) { - Comms comms; + Comms comms; - protocol::Response response; - protocol::Request request; + protocol::Response response; + protocol::Request request; - while(!_this->stop){ - comms.Recv(&request); - _this->HandleRequest(request, response); - comms.Send(response); - } - LOG("%s", "Stop requested"); + while(!_this->stop){ + comms.Recv(&request); + _this->HandleRequest(request, response); + comms.Send(response); + } + LOG("%s", "Stop requested"); } diff --git a/OpenVR-SpaceCalibratorDriver/InterfaceHookInjector.cpp b/OpenVR-SpaceCalibratorDriver/InterfaceHookInjector.cpp index 2c461541..a2fe5b12 100644 --- a/OpenVR-SpaceCalibratorDriver/InterfaceHookInjector.cpp +++ b/OpenVR-SpaceCalibratorDriver/InterfaceHookInjector.cpp @@ -63,7 +63,7 @@ static void *DetourGetGenericInterface(vr::IVRDriverContext *_this, const char * void InjectHooks(ServerTrackedDeviceProvider *driver, vr::IVRDriverContext *pDriverContext) { - LOG("%s", "Injecting hooks"); + LOG("%s", "Injecting hooks"); Driver = driver; auto err = MH_Initialize(); @@ -81,5 +81,5 @@ void InjectHooks(ServerTrackedDeviceProvider *driver, vr::IVRDriverContext *pDri void DisableHooks() { IHook::DestroyAll(); - MH_Uninitialize(); + MH_Uninitialize(); } diff --git a/OpenVR-SpaceCalibratorDriver/Logging.cpp b/OpenVR-SpaceCalibratorDriver/Logging.cpp index 5a6d7f51..33f99538 100644 --- a/OpenVR-SpaceCalibratorDriver/Logging.cpp +++ b/OpenVR-SpaceCalibratorDriver/Logging.cpp @@ -23,9 +23,9 @@ void OpenLogFile() tm TimeForLog() { - if(LogFile == nullptr){ - OpenLogFile(); - } + if(LogFile == nullptr){ + OpenLogFile(); + } auto now = std::chrono::system_clock::now(); auto nowTime = std::chrono::system_clock::to_time_t(now); diff --git a/OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.cpp b/OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.cpp index 3a98a71f..ef84e56b 100644 --- a/OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.cpp +++ b/OpenVR-SpaceCalibratorDriver/ServerTrackedDeviceProvider.cpp @@ -7,8 +7,8 @@ vr::EVRInitError ServerTrackedDeviceProvider::Init(vr::IVRDriverContext *pDriverContext) { - //LOG("%s", "Starting loop break"); - //loopBreak(); + //LOG("%s", "Starting loop break"); + //loopBreak(); TRACE("%s", "ServerTrackedDeviceProvider::Init()"); VR_INIT_SERVER_DRIVER_CONTEXT(pDriverContext); diff --git a/OpenVR-SpaceCalibratorDriver/dllmain.cpp b/OpenVR-SpaceCalibratorDriver/dllmain.cpp index 90ee68d3..41655035 100644 --- a/OpenVR-SpaceCalibratorDriver/dllmain.cpp +++ b/OpenVR-SpaceCalibratorDriver/dllmain.cpp @@ -6,14 +6,14 @@ __attribute__((constructor)) static void loaded(){ - int pid = getpid(); - LOG("OpenVR-SpaceCalibratorDriver " SPACECAL_VERSION_STRING " loaded into pid %d", pid); + int pid = getpid(); + LOG("OpenVR-SpaceCalibratorDriver " SPACECAL_VERSION_STRING " loaded into pid %d", pid); } __attribute__((destructor)) static void unloaded(){ - int pid = getpid(); - LOG("OpenVR-SpaceCalibratorDriver " SPACECAL_VERSION_STRING " unloaded from pid %d", pid); + int pid = getpid(); + LOG("OpenVR-SpaceCalibratorDriver " SPACECAL_VERSION_STRING " unloaded from pid %d", pid); }