libgoatvr
changeset 0:ded3d0a74e19
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 29 Aug 2014 03:45:25 +0300 |
parents | |
children | d861e4d6850f |
files | .hgignore libgoatvr.def libgoatvr.sln libgoatvr.vcxproj libgoatvr.vcxproj.filters libgoatvr_static.vcxproj libgoatvr_static.vcxproj.filters src/mathutil.c src/mathutil.h src/opt.c src/opt.h src/rbtree.c src/rbtree.h src/vr.c src/vr.h src/vr_impl.h src/vr_libovr.c src/vr_modules.c src/vr_null.c src/vr_openhmd.c |
diffstat | 20 files changed, 2218 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/.hgignore Fri Aug 29 03:45:25 2014 +0300 1.3 @@ -0,0 +1,14 @@ 1.4 +\.o$ 1.5 +\.d$ 1.6 +\.swp$ 1.7 +\.so$ 1.8 +\.so\. 1.9 +\.a$ 1.10 +\.dll$ 1.11 +\.lib$ 1.12 +\.obj$ 1.13 +\.suo$ 1.14 +\.sdf$ 1.15 +\.opensdf$ 1.16 +^Debug 1.17 +^Release
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/libgoatvr.def Fri Aug 29 03:45:25 2014 +0300 2.3 @@ -0,0 +1,30 @@ 2.4 +LIBRARY libgoatvr 2.5 +EXPORTS 2.6 + vr_init 2.7 + vr_shutdown 2.8 + 2.9 + vr_module_count 2.10 + vr_module_name 2.11 + 2.12 + vr_use_module 2.13 + vr_use_module_named 2.14 + 2.15 + vr_set_opti 2.16 + vr_set_optf 2.17 + vr_get_opti 2.18 + vr_get_optf 2.19 + 2.20 + vr_view_translation 2.21 + vr_view_rotation 2.22 + 2.23 + vr_view_matrix 2.24 + vr_proj_matrix 2.25 + 2.26 + vr_begin 2.27 + vr_end 2.28 + vr_swap_buffers 2.29 + 2.30 + vr_output_texture 2.31 + vr_output_texture_eye 2.32 + 2.33 + vr_recenter 2.34 \ No newline at end of file
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/libgoatvr.sln Fri Aug 29 03:45:25 2014 +0300 3.3 @@ -0,0 +1,28 @@ 3.4 + 3.5 +Microsoft Visual Studio Solution File, Format Version 12.00 3.6 +# Visual Studio 2013 3.7 +VisualStudioVersion = 12.0.30501.0 3.8 +MinimumVisualStudioVersion = 10.0.40219.1 3.9 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgoatvr", "libgoatvr.vcxproj", "{6AD69AF8-6F44-4D45-A59C-A7A07F6E1CE0}" 3.10 +EndProject 3.11 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgoatvr_static", "libgoatvr_static.vcxproj", "{DF0FC238-A249-432C-9163-3778DDE78A62}" 3.12 +EndProject 3.13 +Global 3.14 + GlobalSection(SolutionConfigurationPlatforms) = preSolution 3.15 + Debug|Win32 = Debug|Win32 3.16 + Release|Win32 = Release|Win32 3.17 + EndGlobalSection 3.18 + GlobalSection(ProjectConfigurationPlatforms) = postSolution 3.19 + {6AD69AF8-6F44-4D45-A59C-A7A07F6E1CE0}.Debug|Win32.ActiveCfg = Debug|Win32 3.20 + {6AD69AF8-6F44-4D45-A59C-A7A07F6E1CE0}.Debug|Win32.Build.0 = Debug|Win32 3.21 + {6AD69AF8-6F44-4D45-A59C-A7A07F6E1CE0}.Release|Win32.ActiveCfg = Release|Win32 3.22 + {6AD69AF8-6F44-4D45-A59C-A7A07F6E1CE0}.Release|Win32.Build.0 = Release|Win32 3.23 + {DF0FC238-A249-432C-9163-3778DDE78A62}.Debug|Win32.ActiveCfg = Debug|Win32 3.24 + {DF0FC238-A249-432C-9163-3778DDE78A62}.Debug|Win32.Build.0 = Debug|Win32 3.25 + {DF0FC238-A249-432C-9163-3778DDE78A62}.Release|Win32.ActiveCfg = Release|Win32 3.26 + {DF0FC238-A249-432C-9163-3778DDE78A62}.Release|Win32.Build.0 = Release|Win32 3.27 + EndGlobalSection 3.28 + GlobalSection(SolutionProperties) = preSolution 3.29 + HideSolutionNode = FALSE 3.30 + EndGlobalSection 3.31 +EndGlobal
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/libgoatvr.vcxproj Fri Aug 29 03:45:25 2014 +0300 4.3 @@ -0,0 +1,107 @@ 4.4 +<?xml version="1.0" encoding="utf-8"?> 4.5 +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 4.6 + <ItemGroup Label="ProjectConfigurations"> 4.7 + <ProjectConfiguration Include="Debug|Win32"> 4.8 + <Configuration>Debug</Configuration> 4.9 + <Platform>Win32</Platform> 4.10 + </ProjectConfiguration> 4.11 + <ProjectConfiguration Include="Release|Win32"> 4.12 + <Configuration>Release</Configuration> 4.13 + <Platform>Win32</Platform> 4.14 + </ProjectConfiguration> 4.15 + </ItemGroup> 4.16 + <PropertyGroup Label="Globals"> 4.17 + <ProjectGuid>{6AD69AF8-6F44-4D45-A59C-A7A07F6E1CE0}</ProjectGuid> 4.18 + <Keyword>Win32Proj</Keyword> 4.19 + <RootNamespace>libgoatvr</RootNamespace> 4.20 + </PropertyGroup> 4.21 + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> 4.22 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> 4.23 + <ConfigurationType>DynamicLibrary</ConfigurationType> 4.24 + <UseDebugLibraries>true</UseDebugLibraries> 4.25 + <PlatformToolset>v120</PlatformToolset> 4.26 + <CharacterSet>MultiByte</CharacterSet> 4.27 + </PropertyGroup> 4.28 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> 4.29 + <ConfigurationType>DynamicLibrary</ConfigurationType> 4.30 + <UseDebugLibraries>false</UseDebugLibraries> 4.31 + <PlatformToolset>v120</PlatformToolset> 4.32 + <WholeProgramOptimization>false</WholeProgramOptimization> 4.33 + <CharacterSet>MultiByte</CharacterSet> 4.34 + </PropertyGroup> 4.35 + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> 4.36 + <ImportGroup Label="ExtensionSettings"> 4.37 + </ImportGroup> 4.38 + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> 4.39 + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> 4.40 + </ImportGroup> 4.41 + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> 4.42 + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> 4.43 + </ImportGroup> 4.44 + <PropertyGroup Label="UserMacros" /> 4.45 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> 4.46 + <LinkIncremental>true</LinkIncremental> 4.47 + </PropertyGroup> 4.48 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> 4.49 + <LinkIncremental>false</LinkIncremental> 4.50 + </PropertyGroup> 4.51 + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> 4.52 + <ClCompile> 4.53 + <PrecompiledHeader> 4.54 + </PrecompiledHeader> 4.55 + <WarningLevel>Level3</WarningLevel> 4.56 + <Optimization>Disabled</Optimization> 4.57 + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBGOATVR_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> 4.58 + <DisableSpecificWarnings>4244;4996</DisableSpecificWarnings> 4.59 + </ClCompile> 4.60 + <Link> 4.61 + <SubSystem>Windows</SubSystem> 4.62 + <GenerateDebugInformation>true</GenerateDebugInformation> 4.63 + <ModuleDefinitionFile>libgoatvr.def</ModuleDefinitionFile> 4.64 + <AdditionalDependencies>opengl32.lib;libovrd.lib;%(AdditionalDependencies)</AdditionalDependencies> 4.65 + </Link> 4.66 + </ItemDefinitionGroup> 4.67 + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> 4.68 + <ClCompile> 4.69 + <WarningLevel>Level3</WarningLevel> 4.70 + <PrecompiledHeader> 4.71 + </PrecompiledHeader> 4.72 + <Optimization>MaxSpeed</Optimization> 4.73 + <FunctionLevelLinking>true</FunctionLevelLinking> 4.74 + <IntrinsicFunctions>true</IntrinsicFunctions> 4.75 + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBGOATVR_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> 4.76 + <DisableSpecificWarnings>4244;4996</DisableSpecificWarnings> 4.77 + </ClCompile> 4.78 + <Link> 4.79 + <SubSystem>Windows</SubSystem> 4.80 + <GenerateDebugInformation>true</GenerateDebugInformation> 4.81 + <EnableCOMDATFolding>true</EnableCOMDATFolding> 4.82 + <OptimizeReferences>true</OptimizeReferences> 4.83 + <ModuleDefinitionFile>libgoatvr.def</ModuleDefinitionFile> 4.84 + <AdditionalDependencies>opengl32.lib;libovr.lib;%(AdditionalDependencies)</AdditionalDependencies> 4.85 + </Link> 4.86 + </ItemDefinitionGroup> 4.87 + <ItemGroup> 4.88 + <ClCompile Include="src\mathutil.c" /> 4.89 + <ClCompile Include="src\opt.c" /> 4.90 + <ClCompile Include="src\rbtree.c" /> 4.91 + <ClCompile Include="src\vr.c" /> 4.92 + <ClCompile Include="src\vr_libovr.c" /> 4.93 + <ClCompile Include="src\vr_modules.c" /> 4.94 + <ClCompile Include="src\vr_null.c" /> 4.95 + <ClCompile Include="src\vr_openhmd.c" /> 4.96 + </ItemGroup> 4.97 + <ItemGroup> 4.98 + <ClInclude Include="src\mathutil.h" /> 4.99 + <ClInclude Include="src\opt.h" /> 4.100 + <ClInclude Include="src\rbtree.h" /> 4.101 + <ClInclude Include="src\vr.h" /> 4.102 + <ClInclude Include="src\vr_impl.h" /> 4.103 + </ItemGroup> 4.104 + <ItemGroup> 4.105 + <None Include="libgoatvr.def" /> 4.106 + </ItemGroup> 4.107 + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> 4.108 + <ImportGroup Label="ExtensionTargets"> 4.109 + </ImportGroup> 4.110 +</Project> 4.111 \ No newline at end of file
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/libgoatvr.vcxproj.filters Fri Aug 29 03:45:25 2014 +0300 5.3 @@ -0,0 +1,55 @@ 5.4 +<?xml version="1.0" encoding="utf-8"?> 5.5 +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 5.6 + <ItemGroup> 5.7 + <Filter Include="src"> 5.8 + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> 5.9 + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;h;inl</Extensions> 5.10 + </Filter> 5.11 + </ItemGroup> 5.12 + <ItemGroup> 5.13 + <ClCompile Include="src\mathutil.c"> 5.14 + <Filter>src</Filter> 5.15 + </ClCompile> 5.16 + <ClCompile Include="src\opt.c"> 5.17 + <Filter>src</Filter> 5.18 + </ClCompile> 5.19 + <ClCompile Include="src\rbtree.c"> 5.20 + <Filter>src</Filter> 5.21 + </ClCompile> 5.22 + <ClCompile Include="src\vr.c"> 5.23 + <Filter>src</Filter> 5.24 + </ClCompile> 5.25 + <ClCompile Include="src\vr_libovr.c"> 5.26 + <Filter>src</Filter> 5.27 + </ClCompile> 5.28 + <ClCompile Include="src\vr_modules.c"> 5.29 + <Filter>src</Filter> 5.30 + </ClCompile> 5.31 + <ClCompile Include="src\vr_null.c"> 5.32 + <Filter>src</Filter> 5.33 + </ClCompile> 5.34 + <ClCompile Include="src\vr_openhmd.c"> 5.35 + <Filter>src</Filter> 5.36 + </ClCompile> 5.37 + </ItemGroup> 5.38 + <ItemGroup> 5.39 + <ClInclude Include="src\mathutil.h"> 5.40 + <Filter>src</Filter> 5.41 + </ClInclude> 5.42 + <ClInclude Include="src\opt.h"> 5.43 + <Filter>src</Filter> 5.44 + </ClInclude> 5.45 + <ClInclude Include="src\rbtree.h"> 5.46 + <Filter>src</Filter> 5.47 + </ClInclude> 5.48 + <ClInclude Include="src\vr.h"> 5.49 + <Filter>src</Filter> 5.50 + </ClInclude> 5.51 + <ClInclude Include="src\vr_impl.h"> 5.52 + <Filter>src</Filter> 5.53 + </ClInclude> 5.54 + </ItemGroup> 5.55 + <ItemGroup> 5.56 + <None Include="libgoatvr.def" /> 5.57 + </ItemGroup> 5.58 +</Project> 5.59 \ No newline at end of file
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/libgoatvr_static.vcxproj Fri Aug 29 03:45:25 2014 +0300 6.3 @@ -0,0 +1,102 @@ 6.4 +<?xml version="1.0" encoding="utf-8"?> 6.5 +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 6.6 + <ItemGroup Label="ProjectConfigurations"> 6.7 + <ProjectConfiguration Include="Debug|Win32"> 6.8 + <Configuration>Debug</Configuration> 6.9 + <Platform>Win32</Platform> 6.10 + </ProjectConfiguration> 6.11 + <ProjectConfiguration Include="Release|Win32"> 6.12 + <Configuration>Release</Configuration> 6.13 + <Platform>Win32</Platform> 6.14 + </ProjectConfiguration> 6.15 + </ItemGroup> 6.16 + <ItemGroup> 6.17 + <ClCompile Include="src\mathutil.c" /> 6.18 + <ClCompile Include="src\opt.c" /> 6.19 + <ClCompile Include="src\rbtree.c" /> 6.20 + <ClCompile Include="src\vr.c" /> 6.21 + <ClCompile Include="src\vr_libovr.c" /> 6.22 + <ClCompile Include="src\vr_modules.c" /> 6.23 + <ClCompile Include="src\vr_null.c" /> 6.24 + <ClCompile Include="src\vr_openhmd.c" /> 6.25 + </ItemGroup> 6.26 + <ItemGroup> 6.27 + <ClInclude Include="src\mathutil.h" /> 6.28 + <ClInclude Include="src\opt.h" /> 6.29 + <ClInclude Include="src\rbtree.h" /> 6.30 + <ClInclude Include="src\vr.h" /> 6.31 + <ClInclude Include="src\vr_impl.h" /> 6.32 + </ItemGroup> 6.33 + <PropertyGroup Label="Globals"> 6.34 + <ProjectGuid>{DF0FC238-A249-432C-9163-3778DDE78A62}</ProjectGuid> 6.35 + <Keyword>Win32Proj</Keyword> 6.36 + <RootNamespace>libgoatvr_static</RootNamespace> 6.37 + </PropertyGroup> 6.38 + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> 6.39 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> 6.40 + <ConfigurationType>StaticLibrary</ConfigurationType> 6.41 + <UseDebugLibraries>true</UseDebugLibraries> 6.42 + <PlatformToolset>v120</PlatformToolset> 6.43 + <CharacterSet>MultiByte</CharacterSet> 6.44 + </PropertyGroup> 6.45 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> 6.46 + <ConfigurationType>StaticLibrary</ConfigurationType> 6.47 + <UseDebugLibraries>false</UseDebugLibraries> 6.48 + <PlatformToolset>v120</PlatformToolset> 6.49 + <WholeProgramOptimization>false</WholeProgramOptimization> 6.50 + <CharacterSet>MultiByte</CharacterSet> 6.51 + </PropertyGroup> 6.52 + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> 6.53 + <ImportGroup Label="ExtensionSettings"> 6.54 + </ImportGroup> 6.55 + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> 6.56 + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> 6.57 + </ImportGroup> 6.58 + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> 6.59 + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> 6.60 + </ImportGroup> 6.61 + <PropertyGroup Label="UserMacros" /> 6.62 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> 6.63 + <IntDir>$(Configuration)_static\</IntDir> 6.64 + <OutDir>$(SolutionDir)$(Configuration)_static\</OutDir> 6.65 + </PropertyGroup> 6.66 + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> 6.67 + <IntDir>$(Configuration)_static\</IntDir> 6.68 + <OutDir>$(SolutionDir)$(Configuration)_static\</OutDir> 6.69 + </PropertyGroup> 6.70 + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> 6.71 + <ClCompile> 6.72 + <PrecompiledHeader> 6.73 + </PrecompiledHeader> 6.74 + <WarningLevel>Level3</WarningLevel> 6.75 + <Optimization>Disabled</Optimization> 6.76 + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> 6.77 + <DisableSpecificWarnings>4244;4996</DisableSpecificWarnings> 6.78 + </ClCompile> 6.79 + <Link> 6.80 + <SubSystem>Windows</SubSystem> 6.81 + <GenerateDebugInformation>true</GenerateDebugInformation> 6.82 + </Link> 6.83 + </ItemDefinitionGroup> 6.84 + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> 6.85 + <ClCompile> 6.86 + <WarningLevel>Level3</WarningLevel> 6.87 + <PrecompiledHeader> 6.88 + </PrecompiledHeader> 6.89 + <Optimization>MaxSpeed</Optimization> 6.90 + <FunctionLevelLinking>true</FunctionLevelLinking> 6.91 + <IntrinsicFunctions>true</IntrinsicFunctions> 6.92 + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> 6.93 + <DisableSpecificWarnings>4244;4996</DisableSpecificWarnings> 6.94 + </ClCompile> 6.95 + <Link> 6.96 + <SubSystem>Windows</SubSystem> 6.97 + <GenerateDebugInformation>true</GenerateDebugInformation> 6.98 + <EnableCOMDATFolding>true</EnableCOMDATFolding> 6.99 + <OptimizeReferences>true</OptimizeReferences> 6.100 + </Link> 6.101 + </ItemDefinitionGroup> 6.102 + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> 6.103 + <ImportGroup Label="ExtensionTargets"> 6.104 + </ImportGroup> 6.105 +</Project> 6.106 \ No newline at end of file
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/libgoatvr_static.vcxproj.filters Fri Aug 29 03:45:25 2014 +0300 7.3 @@ -0,0 +1,52 @@ 7.4 +<?xml version="1.0" encoding="utf-8"?> 7.5 +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 7.6 + <ItemGroup> 7.7 + <Filter Include="src"> 7.8 + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> 7.9 + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;h;inl</Extensions> 7.10 + </Filter> 7.11 + </ItemGroup> 7.12 + <ItemGroup> 7.13 + <ClCompile Include="src\mathutil.c"> 7.14 + <Filter>src</Filter> 7.15 + </ClCompile> 7.16 + <ClCompile Include="src\opt.c"> 7.17 + <Filter>src</Filter> 7.18 + </ClCompile> 7.19 + <ClCompile Include="src\rbtree.c"> 7.20 + <Filter>src</Filter> 7.21 + </ClCompile> 7.22 + <ClCompile Include="src\vr.c"> 7.23 + <Filter>src</Filter> 7.24 + </ClCompile> 7.25 + <ClCompile Include="src\vr_libovr.c"> 7.26 + <Filter>src</Filter> 7.27 + </ClCompile> 7.28 + <ClCompile Include="src\vr_modules.c"> 7.29 + <Filter>src</Filter> 7.30 + </ClCompile> 7.31 + <ClCompile Include="src\vr_null.c"> 7.32 + <Filter>src</Filter> 7.33 + </ClCompile> 7.34 + <ClCompile Include="src\vr_openhmd.c"> 7.35 + <Filter>src</Filter> 7.36 + </ClCompile> 7.37 + </ItemGroup> 7.38 + <ItemGroup> 7.39 + <ClInclude Include="src\mathutil.h"> 7.40 + <Filter>src</Filter> 7.41 + </ClInclude> 7.42 + <ClInclude Include="src\opt.h"> 7.43 + <Filter>src</Filter> 7.44 + </ClInclude> 7.45 + <ClInclude Include="src\rbtree.h"> 7.46 + <Filter>src</Filter> 7.47 + </ClInclude> 7.48 + <ClInclude Include="src\vr.h"> 7.49 + <Filter>src</Filter> 7.50 + </ClInclude> 7.51 + <ClInclude Include="src\vr_impl.h"> 7.52 + <Filter>src</Filter> 7.53 + </ClInclude> 7.54 + </ItemGroup> 7.55 +</Project> 7.56 \ No newline at end of file
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/mathutil.c Fri Aug 29 03:45:25 2014 +0300 8.3 @@ -0,0 +1,78 @@ 8.4 +#include <stdio.h> 8.5 +#include <string.h> 8.6 +#include "mathutil.h" 8.7 + 8.8 +#define M(i, j) ((i) * 4 + (j)) 8.9 + 8.10 +static const float idmat[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; 8.11 + 8.12 +void rotation_matrix(const float *quat, float *matrix) 8.13 +{ 8.14 + matrix[0] = 1.0 - 2.0 * quat[1] * quat[1] - 2.0 * quat[2] * quat[2]; 8.15 + matrix[1] = 2.0 * quat[0] * quat[1] + 2.0 * quat[3] * quat[2]; 8.16 + matrix[2] = 2.0 * quat[2] * quat[0] - 2.0 * quat[3] * quat[1]; 8.17 + matrix[3] = 0.0f; 8.18 + 8.19 + matrix[4] = 2.0 * quat[0] * quat[1] - 2.0 * quat[3] * quat[2]; 8.20 + matrix[5] = 1.0 - 2.0 * quat[0]*quat[0] - 2.0 * quat[2]*quat[2]; 8.21 + matrix[6] = 2.0 * quat[1] * quat[2] + 2.0 * quat[3] * quat[0]; 8.22 + matrix[7] = 0.0f; 8.23 + 8.24 + matrix[8] = 2.0 * quat[2] * quat[0] + 2.0 * quat[3] * quat[1]; 8.25 + matrix[9] = 2.0 * quat[1] * quat[2] - 2.0 * quat[3] * quat[0]; 8.26 + matrix[10] = 1.0 - 2.0 * quat[0]*quat[0] - 2.0 * quat[1]*quat[1]; 8.27 + matrix[11] = 0.0f; 8.28 + 8.29 + matrix[12] = matrix[13] = matrix[14] = 0.0f; 8.30 + matrix[15] = 1.0f; 8.31 + 8.32 + transpose_matrix(matrix); 8.33 +} 8.34 + 8.35 +void translation_matrix(const float *vec, float *matrix) 8.36 +{ 8.37 + memcpy(matrix, idmat, sizeof idmat); 8.38 + matrix[12] = vec[0]; 8.39 + matrix[13] = vec[1]; 8.40 + matrix[14] = vec[2]; 8.41 +} 8.42 + 8.43 +void mult_matrix(float *dest, const float *m1, const float *m2) 8.44 +{ 8.45 + int i, j; 8.46 + float tmp[16]; 8.47 + 8.48 + for(i=0; i<4; i++) { 8.49 + for(j=0; j<4; j++) { 8.50 + tmp[M(i, j)] = m1[M(i, 0)] * m2[M(0, j)] + m1[M(i, 1)] * m2[M(1, j)] + 8.51 + m1[M(i, 2)] * m2[M(2, j)] + m1[M(i, 3)] * m2[M(3, j)]; 8.52 + } 8.53 + } 8.54 + memcpy(dest, tmp, sizeof tmp); 8.55 +} 8.56 + 8.57 +void transpose_matrix(float *matrix) 8.58 +{ 8.59 + int i, j; 8.60 + float tmp[16]; 8.61 + 8.62 + for(i=0; i<4; i++) { 8.63 + for(j=0; j<4; j++) { 8.64 + tmp[M(i, j)] = matrix[M(j, i)]; 8.65 + } 8.66 + } 8.67 + memcpy(matrix, tmp, sizeof tmp); 8.68 +} 8.69 + 8.70 +void print_matrix(const float *matrix) 8.71 +{ 8.72 + int i, j; 8.73 + 8.74 + for(i=0; i<4; i++) { 8.75 + putchar('['); 8.76 + for(j=0; j<4; j++) { 8.77 + printf("%6.3f ", matrix[M(i, j)]); 8.78 + } 8.79 + printf("]\n"); 8.80 + } 8.81 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/mathutil.h Fri Aug 29 03:45:25 2014 +0300 9.3 @@ -0,0 +1,13 @@ 9.4 +#ifndef MATHUTIL_H_ 9.5 +#define MATHUTIL_H_ 9.6 + 9.7 +void rotation_matrix(const float *quat, float *matrix); 9.8 +void translation_matrix(const float *vec, float *matrix); 9.9 + 9.10 +void mult_matrix(float *dest, const float *m1, const float *m2); 9.11 + 9.12 +void transpose_matrix(float *matrix); 9.13 + 9.14 +void print_matrix(const float *matrix); 9.15 + 9.16 +#endif /* MATHUTIL_H_ */
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/opt.c Fri Aug 29 03:45:25 2014 +0300 10.3 @@ -0,0 +1,77 @@ 10.4 +#include <stdio.h> 10.5 +#include <stdlib.h> 10.6 +#include <string.h> 10.7 +#include <errno.h> 10.8 +#include "opt.h" 10.9 +#include "rbtree.h" 10.10 + 10.11 +static void opt_del_func(struct rbnode *opt, void *cls) 10.12 +{ 10.13 + free(opt); 10.14 +} 10.15 + 10.16 +void *create_options(void) 10.17 +{ 10.18 + struct rbtree *db = rb_create(RB_KEY_STRING); 10.19 + rb_set_delete_func(db, opt_del_func, 0); 10.20 + return db; 10.21 +} 10.22 + 10.23 +void destroy_options(void *optdb) 10.24 +{ 10.25 + rb_destroy(optdb); 10.26 +} 10.27 + 10.28 +void set_option_int(void *optdb, const char *key, int val) 10.29 +{ 10.30 + struct option *opt = malloc(sizeof *opt); 10.31 + if(!opt) { 10.32 + fprintf(stderr, "failed to set option: %s: %s\n", key, strerror(errno)); 10.33 + return; 10.34 + } 10.35 + opt->type = OTYPE_INT; 10.36 + opt->ival = val; 10.37 + opt->fval = (float)val; 10.38 + 10.39 + if(rb_insert(optdb, (void*)key, opt) == -1) { 10.40 + fprintf(stderr, "failed to set option: %s\n", key); 10.41 + } 10.42 +} 10.43 + 10.44 +void set_option_float(void *optdb, const char *key, float val) 10.45 +{ 10.46 + struct option *opt = malloc(sizeof *opt); 10.47 + if(!opt) { 10.48 + fprintf(stderr, "failed to set option: %s: %s\n", key, strerror(errno)); 10.49 + return; 10.50 + } 10.51 + opt->type = OTYPE_FLOAT; 10.52 + opt->fval = val; 10.53 + opt->ival = (int)val; 10.54 + 10.55 + if(rb_insert(optdb, (void*)key, opt) == -1) { 10.56 + fprintf(stderr, "failed to set option: %s\n", key); 10.57 + } 10.58 +} 10.59 + 10.60 +int get_option_int(void *optdb, const char *key, int *val) 10.61 +{ 10.62 + struct option *opt = rb_find(optdb, (void*)key); 10.63 + if(!opt) { 10.64 + *val = 0; 10.65 + return -1; 10.66 + } 10.67 + *val = opt->ival; 10.68 + return 0; 10.69 +} 10.70 + 10.71 +int get_option_float(void *optdb, const char *key, float *val) 10.72 +{ 10.73 + struct option *opt = rb_find(optdb, (void*)key); 10.74 + if(!opt) { 10.75 + *val = 0.0f; 10.76 + return -1; 10.77 + } 10.78 + *val = opt->fval; 10.79 + return 0; 10.80 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/src/opt.h Fri Aug 29 03:45:25 2014 +0300 11.3 @@ -0,0 +1,21 @@ 11.4 +#ifndef OPT_H_ 11.5 +#define OPT_H_ 11.6 + 11.7 +enum opt_type { OTYPE_INT, OTYPE_FLOAT }; 11.8 + 11.9 +struct option { 11.10 + enum opt_type type; 11.11 + int ival; 11.12 + float fval; 11.13 +}; 11.14 + 11.15 +void *create_options(void); 11.16 +void destroy_options(void *optdb); 11.17 + 11.18 +void set_option_int(void *optdb, const char *key, int val); 11.19 +void set_option_float(void *optdb, const char *key, float val); 11.20 + 11.21 +int get_option_int(void *optdb, const char *key, int *val); 11.22 +int get_option_float(void *optdb, const char *key, float *val); 11.23 + 11.24 +#endif /* OPT_H_ */
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/src/rbtree.c Fri Aug 29 03:45:25 2014 +0300 12.3 @@ -0,0 +1,501 @@ 12.4 +/* 12.5 +rbtree - simple balanced binary search tree (red-black tree) library. 12.6 +Copyright (C) 2011-2014 John Tsiombikas <nuclear@member.fsf.org> 12.7 + 12.8 +rbtree is free software, feel free to use, modify, and redistribute it, under 12.9 +the terms of the 3-clause BSD license. See COPYING for details. 12.10 + */ 12.11 +#include <stdio.h> 12.12 +#include <stdlib.h> 12.13 +#include <stdint.h> 12.14 +#include <string.h> 12.15 +#include "rbtree.h" 12.16 + 12.17 +#define INT2PTR(x) ((void*)(intptr_t)(x)) 12.18 +#define PTR2INT(x) ((int)(intptr_t)(x)) 12.19 + 12.20 +struct rbtree { 12.21 + struct rbnode *root; 12.22 + 12.23 + rb_alloc_func_t alloc; 12.24 + rb_free_func_t free; 12.25 + 12.26 + rb_cmp_func_t cmp; 12.27 + rb_del_func_t del; 12.28 + void *del_cls; 12.29 + 12.30 + struct rbnode *rstack, *iter; 12.31 +}; 12.32 + 12.33 +static int cmpaddr(const void *ap, const void *bp); 12.34 +static int cmpint(const void *ap, const void *bp); 12.35 + 12.36 +static int count_nodes(struct rbnode *node); 12.37 +static void del_tree(struct rbnode *node, void (*delfunc)(struct rbnode*, void*), void *cls); 12.38 +static struct rbnode *insert(struct rbtree *rb, struct rbnode *tree, void *key, void *data); 12.39 +static struct rbnode *delete(struct rbtree *rb, struct rbnode *tree, void *key); 12.40 +/*static struct rbnode *find(struct rbtree *rb, struct rbnode *node, void *key);*/ 12.41 +static void traverse(struct rbnode *node, void (*func)(struct rbnode*, void*), void *cls); 12.42 + 12.43 +struct rbtree *rb_create(rb_cmp_func_t cmp_func) 12.44 +{ 12.45 + struct rbtree *rb; 12.46 + 12.47 + if(!(rb = malloc(sizeof *rb))) { 12.48 + return 0; 12.49 + } 12.50 + if(rb_init(rb, cmp_func) == -1) { 12.51 + free(rb); 12.52 + return 0; 12.53 + } 12.54 + return rb; 12.55 +} 12.56 + 12.57 +void rb_free(struct rbtree *rb) 12.58 +{ 12.59 + rb_destroy(rb); 12.60 + free(rb); 12.61 +} 12.62 + 12.63 + 12.64 +int rb_init(struct rbtree *rb, rb_cmp_func_t cmp_func) 12.65 +{ 12.66 + memset(rb, 0, sizeof *rb); 12.67 + 12.68 + if(cmp_func == RB_KEY_INT) { 12.69 + rb->cmp = cmpint; 12.70 + } else if(cmp_func == RB_KEY_STRING) { 12.71 + rb->cmp = (rb_cmp_func_t)strcmp; 12.72 + } else { 12.73 + rb->cmp = cmpaddr; 12.74 + } 12.75 + 12.76 + rb->alloc = malloc; 12.77 + rb->free = free; 12.78 + return 0; 12.79 +} 12.80 + 12.81 +void rb_destroy(struct rbtree *rb) 12.82 +{ 12.83 + del_tree(rb->root, rb->del, rb->del_cls); 12.84 +} 12.85 + 12.86 +void rb_set_allocator(struct rbtree *rb, rb_alloc_func_t alloc, rb_free_func_t free) 12.87 +{ 12.88 + rb->alloc = alloc; 12.89 + rb->free = free; 12.90 +} 12.91 + 12.92 + 12.93 +void rb_set_compare_func(struct rbtree *rb, rb_cmp_func_t func) 12.94 +{ 12.95 + rb->cmp = func; 12.96 +} 12.97 + 12.98 +void rb_set_delete_func(struct rbtree *rb, rb_del_func_t func, void *cls) 12.99 +{ 12.100 + rb->del = func; 12.101 + rb->del_cls = cls; 12.102 +} 12.103 + 12.104 + 12.105 +void rb_clear(struct rbtree *rb) 12.106 +{ 12.107 + del_tree(rb->root, rb->del, rb->del_cls); 12.108 + rb->root = 0; 12.109 +} 12.110 + 12.111 +int rb_copy(struct rbtree *dest, struct rbtree *src) 12.112 +{ 12.113 + struct rbnode *node; 12.114 + 12.115 + rb_clear(dest); 12.116 + rb_begin(src); 12.117 + while((node = rb_next(src))) { 12.118 + if(rb_insert(dest, node->key, node->data) == -1) { 12.119 + return -1; 12.120 + } 12.121 + } 12.122 + return 0; 12.123 +} 12.124 + 12.125 +int rb_size(struct rbtree *rb) 12.126 +{ 12.127 + return count_nodes(rb->root); 12.128 +} 12.129 + 12.130 +int rb_insert(struct rbtree *rb, void *key, void *data) 12.131 +{ 12.132 + rb->root = insert(rb, rb->root, key, data); 12.133 + rb->root->red = 0; 12.134 + return 0; 12.135 +} 12.136 + 12.137 +int rb_inserti(struct rbtree *rb, int key, void *data) 12.138 +{ 12.139 + rb->root = insert(rb, rb->root, INT2PTR(key), data); 12.140 + rb->root->red = 0; 12.141 + return 0; 12.142 +} 12.143 + 12.144 + 12.145 +int rb_delete(struct rbtree *rb, void *key) 12.146 +{ 12.147 + rb->root = delete(rb, rb->root, key); 12.148 + rb->root->red = 0; 12.149 + return 0; 12.150 +} 12.151 + 12.152 +int rb_deletei(struct rbtree *rb, int key) 12.153 +{ 12.154 + rb->root = delete(rb, rb->root, INT2PTR(key)); 12.155 + rb->root->red = 0; 12.156 + return 0; 12.157 +} 12.158 + 12.159 + 12.160 +void *rb_find(struct rbtree *rb, void *key) 12.161 +{ 12.162 + struct rbnode *node = rb->root; 12.163 + 12.164 + while(node) { 12.165 + int cmp = rb->cmp(key, node->key); 12.166 + if(cmp == 0) { 12.167 + return node->data; 12.168 + } 12.169 + node = cmp < 0 ? node->left : node->right; 12.170 + } 12.171 + return 0; 12.172 +} 12.173 + 12.174 +void *rb_findi(struct rbtree *rb, int key) 12.175 +{ 12.176 + return rb_find(rb, INT2PTR(key)); 12.177 +} 12.178 + 12.179 + 12.180 +void rb_foreach(struct rbtree *rb, void (*func)(struct rbnode*, void*), void *cls) 12.181 +{ 12.182 + traverse(rb->root, func, cls); 12.183 +} 12.184 + 12.185 + 12.186 +struct rbnode *rb_root(struct rbtree *rb) 12.187 +{ 12.188 + return rb->root; 12.189 +} 12.190 + 12.191 +void rb_begin(struct rbtree *rb) 12.192 +{ 12.193 + rb->rstack = 0; 12.194 + rb->iter = rb->root; 12.195 +} 12.196 + 12.197 +#define push(sp, x) ((x)->next = (sp), (sp) = (x)) 12.198 +#define pop(sp) ((sp) = (sp)->next) 12.199 +#define top(sp) (sp) 12.200 + 12.201 +struct rbnode *rb_next(struct rbtree *rb) 12.202 +{ 12.203 + struct rbnode *res = 0; 12.204 + 12.205 + while(rb->rstack || rb->iter) { 12.206 + if(rb->iter) { 12.207 + push(rb->rstack, rb->iter); 12.208 + rb->iter = rb->iter->left; 12.209 + } else { 12.210 + rb->iter = top(rb->rstack); 12.211 + pop(rb->rstack); 12.212 + res = rb->iter; 12.213 + rb->iter = rb->iter->right; 12.214 + break; 12.215 + } 12.216 + } 12.217 + return res; 12.218 +} 12.219 + 12.220 +void *rb_node_key(struct rbnode *node) 12.221 +{ 12.222 + return node ? node->key : 0; 12.223 +} 12.224 + 12.225 +int rb_node_keyi(struct rbnode *node) 12.226 +{ 12.227 + return node ? PTR2INT(node->key) : 0; 12.228 +} 12.229 + 12.230 +void *rb_node_data(struct rbnode *node) 12.231 +{ 12.232 + return node ? node->data : 0; 12.233 +} 12.234 + 12.235 +static int cmpaddr(const void *ap, const void *bp) 12.236 +{ 12.237 + return ap < bp ? -1 : (ap > bp ? 1 : 0); 12.238 +} 12.239 + 12.240 +static int cmpint(const void *ap, const void *bp) 12.241 +{ 12.242 + return PTR2INT(ap) - PTR2INT(bp); 12.243 +} 12.244 + 12.245 + 12.246 +/* ---- left-leaning 2-3 red-black implementation ---- */ 12.247 + 12.248 +/* helper prototypes */ 12.249 +static int is_red(struct rbnode *tree); 12.250 +static void color_flip(struct rbnode *tree); 12.251 +static struct rbnode *rot_left(struct rbnode *a); 12.252 +static struct rbnode *rot_right(struct rbnode *a); 12.253 +static struct rbnode *find_min(struct rbnode *tree); 12.254 +static struct rbnode *del_min(struct rbtree *rb, struct rbnode *tree); 12.255 +/*static struct rbnode *move_red_right(struct rbnode *tree);*/ 12.256 +static struct rbnode *move_red_left(struct rbnode *tree); 12.257 +static struct rbnode *fix_up(struct rbnode *tree); 12.258 + 12.259 +static int count_nodes(struct rbnode *node) 12.260 +{ 12.261 + if(!node) 12.262 + return 0; 12.263 + 12.264 + return 1 + count_nodes(node->left) + count_nodes(node->right); 12.265 +} 12.266 + 12.267 +static void del_tree(struct rbnode *node, rb_del_func_t delfunc, void *cls) 12.268 +{ 12.269 + if(!node) 12.270 + return; 12.271 + 12.272 + del_tree(node->left, delfunc, cls); 12.273 + del_tree(node->right, delfunc, cls); 12.274 + 12.275 + if(delfunc) { 12.276 + delfunc(node, cls); 12.277 + } 12.278 + free(node); 12.279 +} 12.280 + 12.281 +static struct rbnode *insert(struct rbtree *rb, struct rbnode *tree, void *key, void *data) 12.282 +{ 12.283 + int cmp; 12.284 + 12.285 + if(!tree) { 12.286 + struct rbnode *node = rb->alloc(sizeof *node); 12.287 + node->red = 1; 12.288 + node->key = key; 12.289 + node->data = data; 12.290 + node->left = node->right = 0; 12.291 + return node; 12.292 + } 12.293 + 12.294 + cmp = rb->cmp(key, tree->key); 12.295 + 12.296 + if(cmp < 0) { 12.297 + tree->left = insert(rb, tree->left, key, data); 12.298 + } else if(cmp > 0) { 12.299 + tree->right = insert(rb, tree->right, key, data); 12.300 + } else { 12.301 + tree->data = data; 12.302 + } 12.303 + 12.304 + /* fix right-leaning reds */ 12.305 + if(is_red(tree->right)) { 12.306 + tree = rot_left(tree); 12.307 + } 12.308 + /* fix two reds in a row */ 12.309 + if(is_red(tree->left) && is_red(tree->left->left)) { 12.310 + tree = rot_right(tree); 12.311 + } 12.312 + 12.313 + /* if 4-node, split it by color inversion */ 12.314 + if(is_red(tree->left) && is_red(tree->right)) { 12.315 + color_flip(tree); 12.316 + } 12.317 + 12.318 + return tree; 12.319 +} 12.320 + 12.321 +static struct rbnode *delete(struct rbtree *rb, struct rbnode *tree, void *key) 12.322 +{ 12.323 + int cmp; 12.324 + 12.325 + if(!tree) { 12.326 + return 0; 12.327 + } 12.328 + 12.329 + cmp = rb->cmp(key, tree->key); 12.330 + 12.331 + if(cmp < 0) { 12.332 + if(!is_red(tree->left) && !is_red(tree->left->left)) { 12.333 + tree = move_red_left(tree); 12.334 + } 12.335 + tree->left = delete(rb, tree->left, key); 12.336 + } else { 12.337 + /* need reds on the right */ 12.338 + if(is_red(tree->left)) { 12.339 + tree = rot_right(tree); 12.340 + } 12.341 + 12.342 + /* found it at the bottom (XXX what certifies left is null?) */ 12.343 + if(cmp == 0 && !tree->right) { 12.344 + if(rb->del) { 12.345 + rb->del(tree, rb->del_cls); 12.346 + } 12.347 + rb->free(tree); 12.348 + return 0; 12.349 + } 12.350 + 12.351 + if(!is_red(tree->right) && !is_red(tree->right->left)) { 12.352 + tree = move_red_left(tree); 12.353 + } 12.354 + 12.355 + if(key == tree->key) { 12.356 + struct rbnode *rmin = find_min(tree->right); 12.357 + tree->key = rmin->key; 12.358 + tree->data = rmin->data; 12.359 + tree->right = del_min(rb, tree->right); 12.360 + } else { 12.361 + tree->right = delete(rb, tree->right, key); 12.362 + } 12.363 + } 12.364 + 12.365 + return fix_up(tree); 12.366 +} 12.367 + 12.368 +/*static struct rbnode *find(struct rbtree *rb, struct rbnode *node, void *key) 12.369 +{ 12.370 + int cmp; 12.371 + 12.372 + if(!node) 12.373 + return 0; 12.374 + 12.375 + if((cmp = rb->cmp(key, node->key)) == 0) { 12.376 + return node; 12.377 + } 12.378 + return find(rb, cmp < 0 ? node->left : node->right, key); 12.379 +}*/ 12.380 + 12.381 +static void traverse(struct rbnode *node, void (*func)(struct rbnode*, void*), void *cls) 12.382 +{ 12.383 + if(!node) 12.384 + return; 12.385 + 12.386 + traverse(node->left, func, cls); 12.387 + func(node, cls); 12.388 + traverse(node->right, func, cls); 12.389 +} 12.390 + 12.391 +/* helpers */ 12.392 + 12.393 +static int is_red(struct rbnode *tree) 12.394 +{ 12.395 + return tree && tree->red; 12.396 +} 12.397 + 12.398 +static void color_flip(struct rbnode *tree) 12.399 +{ 12.400 + tree->red = !tree->red; 12.401 + tree->left->red = !tree->left->red; 12.402 + tree->right->red = !tree->right->red; 12.403 +} 12.404 + 12.405 +static struct rbnode *rot_left(struct rbnode *a) 12.406 +{ 12.407 + struct rbnode *b = a->right; 12.408 + a->right = b->left; 12.409 + b->left = a; 12.410 + b->red = a->red; 12.411 + a->red = 1; 12.412 + return b; 12.413 +} 12.414 + 12.415 +static struct rbnode *rot_right(struct rbnode *a) 12.416 +{ 12.417 + struct rbnode *b = a->left; 12.418 + a->left = b->right; 12.419 + b->right = a; 12.420 + b->red = a->red; 12.421 + a->red = 1; 12.422 + return b; 12.423 +} 12.424 + 12.425 +static struct rbnode *find_min(struct rbnode *tree) 12.426 +{ 12.427 + struct rbnode *node = tree; 12.428 + 12.429 + if(!tree) 12.430 + return 0; 12.431 + 12.432 + while(node->left) { 12.433 + node = node->left; 12.434 + } 12.435 + return node; 12.436 +} 12.437 + 12.438 +static struct rbnode *del_min(struct rbtree *rb, struct rbnode *tree) 12.439 +{ 12.440 + if(!tree->left) { 12.441 + if(rb->del) { 12.442 + rb->del(tree->left, rb->del_cls); 12.443 + } 12.444 + rb->free(tree->left); 12.445 + return 0; 12.446 + } 12.447 + 12.448 + /* make sure we've got red (3/4-nodes) at the left side so we can delete at the bottom */ 12.449 + if(!is_red(tree->left) && !is_red(tree->left->left)) { 12.450 + tree = move_red_left(tree); 12.451 + } 12.452 + tree->left = del_min(rb, tree->left); 12.453 + 12.454 + /* fix right-reds, red-reds, and split 4-nodes on the way up */ 12.455 + return fix_up(tree); 12.456 +} 12.457 + 12.458 +#if 0 12.459 +/* push a red link on this node to the right */ 12.460 +static struct rbnode *move_red_right(struct rbnode *tree) 12.461 +{ 12.462 + /* flipping it makes both children go red, so we have a red to the right */ 12.463 + color_flip(tree); 12.464 + 12.465 + /* if after the flip we've got a red-red situation to the left, fix it */ 12.466 + if(is_red(tree->left->left)) { 12.467 + tree = rot_right(tree); 12.468 + color_flip(tree); 12.469 + } 12.470 + return tree; 12.471 +} 12.472 +#endif 12.473 + 12.474 +/* push a red link on this node to the left */ 12.475 +static struct rbnode *move_red_left(struct rbnode *tree) 12.476 +{ 12.477 + /* flipping it makes both children go red, so we have a red to the left */ 12.478 + color_flip(tree); 12.479 + 12.480 + /* if after the flip we've got a red-red on the right-left, fix it */ 12.481 + if(is_red(tree->right->left)) { 12.482 + tree->right = rot_right(tree->right); 12.483 + tree = rot_left(tree); 12.484 + color_flip(tree); 12.485 + } 12.486 + return tree; 12.487 +} 12.488 + 12.489 +static struct rbnode *fix_up(struct rbnode *tree) 12.490 +{ 12.491 + /* fix right-leaning */ 12.492 + if(is_red(tree->right)) { 12.493 + tree = rot_left(tree); 12.494 + } 12.495 + /* change invalid red-red pairs into a proper 4-node */ 12.496 + if(is_red(tree->left) && is_red(tree->left->left)) { 12.497 + tree = rot_right(tree); 12.498 + } 12.499 + /* split 4-nodes */ 12.500 + if(is_red(tree->left) && is_red(tree->right)) { 12.501 + color_flip(tree); 12.502 + } 12.503 + return tree; 12.504 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/src/rbtree.h Fri Aug 29 03:45:25 2014 +0300 13.3 @@ -0,0 +1,78 @@ 13.4 +/* 13.5 +rbtree - simple balanced binary search tree (red-black tree) library. 13.6 +Copyright (C) 2011-2014 John Tsiombikas <nuclear@member.fsf.org> 13.7 + 13.8 +rbtree is free software, feel free to use, modify, and redistribute it, under 13.9 +the terms of the 3-clause BSD license. See COPYING for details. 13.10 + */ 13.11 +#ifndef RBTREE_H_ 13.12 +#define RBTREE_H_ 13.13 + 13.14 +struct rbtree; 13.15 + 13.16 + 13.17 +struct rbnode { 13.18 + void *key, *data; 13.19 + int red; 13.20 + struct rbnode *left, *right; 13.21 + struct rbnode *next; /* for iterator stack */ 13.22 +}; 13.23 + 13.24 + 13.25 +typedef void *(*rb_alloc_func_t)(size_t); 13.26 +typedef void (*rb_free_func_t)(void*); 13.27 + 13.28 +typedef int (*rb_cmp_func_t)(const void*, const void*); 13.29 +typedef void (*rb_del_func_t)(struct rbnode*, void*); 13.30 + 13.31 +#define RB_KEY_ADDR (rb_cmp_func_t)(0) 13.32 +#define RB_KEY_INT (rb_cmp_func_t)(1) 13.33 +#define RB_KEY_STRING (rb_cmp_func_t)(3) 13.34 + 13.35 + 13.36 +#ifdef __cplusplus 13.37 +extern "C" { 13.38 +#endif 13.39 + 13.40 +struct rbtree *rb_create(rb_cmp_func_t cmp_func); 13.41 +void rb_free(struct rbtree *rb); 13.42 + 13.43 +int rb_init(struct rbtree *rb, rb_cmp_func_t cmp_func); 13.44 +void rb_destroy(struct rbtree *rb); 13.45 + 13.46 +void rb_set_allocator(struct rbtree *rb, rb_alloc_func_t alloc, rb_free_func_t free); 13.47 +void rb_set_compare_func(struct rbtree *rb, rb_cmp_func_t func); 13.48 +void rb_set_delete_func(struct rbtree *rb, rb_del_func_t func, void *cls); 13.49 +/* TODO add user deep copy function */ 13.50 + 13.51 +void rb_clear(struct rbtree *rb); 13.52 +int rb_copy(struct rbtree *dest, struct rbtree *src); 13.53 + 13.54 +int rb_size(struct rbtree *rb); 13.55 + 13.56 +int rb_insert(struct rbtree *rb, void *key, void *data); 13.57 +int rb_inserti(struct rbtree *rb, int key, void *data); 13.58 + 13.59 +int rb_delete(struct rbtree *rb, void *key); 13.60 +int rb_deletei(struct rbtree *rb, int key); 13.61 + 13.62 +void *rb_find(struct rbtree *rb, void *key); 13.63 +void *rb_findi(struct rbtree *rb, int key); 13.64 + 13.65 +void rb_foreach(struct rbtree *rb, void (*func)(struct rbnode*, void*), void *cls); 13.66 + 13.67 +struct rbnode *rb_root(struct rbtree *rb); 13.68 + 13.69 +void rb_begin(struct rbtree *rb); 13.70 +struct rbnode *rb_next(struct rbtree *rb); 13.71 + 13.72 +void *rb_node_key(struct rbnode *node); 13.73 +int rb_node_keyi(struct rbnode *node); 13.74 +void *rb_node_data(struct rbnode *node); 13.75 + 13.76 +#ifdef __cplusplus 13.77 +} 13.78 +#endif 13.79 + 13.80 + 13.81 +#endif /* RBTREE_H_ */
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/src/vr.c Fri Aug 29 03:45:25 2014 +0300 14.3 @@ -0,0 +1,260 @@ 14.4 +#include <stdio.h> 14.5 +#include <string.h> 14.6 +#include "vr.h" 14.7 +#include "vr_impl.h" 14.8 +#include "mathutil.h" 14.9 + 14.10 + 14.11 +static void swap_buffers(void); 14.12 + 14.13 + 14.14 +static struct vr_module *vrm; 14.15 +static float idmat[] = { 14.16 + 1, 0, 0, 0, 14.17 + 0, 1, 0, 0, 14.18 + 0, 0, 1, 0, 14.19 + 0, 0, 0, 1 14.20 +}; 14.21 +static float fbtex_rect[] = { 14.22 + 0, 0, 1, 1 14.23 +}; 14.24 + 14.25 +int vr_init(void) 14.26 +{ 14.27 + int i, nmodules; 14.28 + 14.29 + if(vrm) { 14.30 + vr_shutdown(); 14.31 + } 14.32 + 14.33 + vr_init_modules(); 14.34 + 14.35 + nmodules = vr_get_num_modules(); 14.36 + for(i=0; i<nmodules; i++) { 14.37 + struct vr_module *m = vr_get_module(i); 14.38 + if(m->init() != -1) { 14.39 + /* add to the active modules array */ 14.40 + vr_activate_module(i); 14.41 + if(!vrm) { 14.42 + vr_use_module(0); 14.43 + } 14.44 + } 14.45 + } 14.46 + 14.47 + if(!vrm) { 14.48 + return -1; 14.49 + } 14.50 + return 0; 14.51 +} 14.52 + 14.53 +void vr_shutdown(void) 14.54 +{ 14.55 + vr_clear_modules(); 14.56 + vrm = 0; 14.57 + fbtex_rect[0] = fbtex_rect[1] = 0; 14.58 + fbtex_rect[2] = fbtex_rect[3] = 1; 14.59 +} 14.60 + 14.61 +int vr_module_count(void) 14.62 +{ 14.63 + return vr_get_num_active_modules(); 14.64 +} 14.65 + 14.66 +const char *vr_module_name(int idx) 14.67 +{ 14.68 + struct vr_module *m = vr_get_active_module(idx); 14.69 + if(!m) { 14.70 + return 0; 14.71 + } 14.72 + return m->name; 14.73 +} 14.74 + 14.75 +int vr_use_module(int idx) 14.76 +{ 14.77 + if(idx >= 0 && idx < vr_get_num_active_modules()) { 14.78 + struct vr_module *m = vr_get_active_module(idx); 14.79 + if(m != vrm) { 14.80 + vrm = m; 14.81 + printf("using vr module: %s\n", vrm->name); 14.82 + } 14.83 + return 0; 14.84 + } 14.85 + return -1; 14.86 +} 14.87 + 14.88 +int vr_use_module_named(const char *name) 14.89 +{ 14.90 + int i, count = vr_get_num_active_modules(); 14.91 + 14.92 + for(i=0; i<count; i++) { 14.93 + struct vr_module *m = vr_get_active_module(i); 14.94 + if(strcmp(m->name, name) == 0) { 14.95 + return vr_use_module(i); 14.96 + } 14.97 + } 14.98 + return -1; 14.99 +} 14.100 + 14.101 +void vr_set_opti(const char *optname, int val) 14.102 +{ 14.103 + if(vrm && vrm->set_option) { 14.104 + vrm->set_option(optname, OTYPE_INT, &val); 14.105 + } 14.106 +} 14.107 + 14.108 +void vr_set_optf(const char *optname, float val) 14.109 +{ 14.110 + if(vrm && vrm->set_option) { 14.111 + vrm->set_option(optname, OTYPE_FLOAT, &val); 14.112 + } 14.113 +} 14.114 + 14.115 +int vr_get_opti(const char *optname) 14.116 +{ 14.117 + int res = 0; 14.118 + 14.119 + if(vrm && vrm->get_option) { 14.120 + vrm->get_option(optname, OTYPE_INT, &res); 14.121 + } 14.122 + return res; 14.123 +} 14.124 + 14.125 +float vr_get_optf(const char *optname) 14.126 +{ 14.127 + float res = 0.0f; 14.128 + 14.129 + if(vrm && vrm->get_option) { 14.130 + vrm->get_option(optname, OTYPE_FLOAT, &res); 14.131 + } 14.132 + return res; 14.133 +} 14.134 + 14.135 + 14.136 +int vr_view_translation(int eye, float *vec) 14.137 +{ 14.138 + if(vrm && vrm->translation) { 14.139 + vrm->translation(eye, vec); 14.140 + return 1; 14.141 + } 14.142 + vec[0] = vec[1] = vec[2] = 0.0f; 14.143 + return 0; 14.144 +} 14.145 + 14.146 +int vr_view_rotation(int eye, float *quat) 14.147 +{ 14.148 + if(vrm && vrm->rotation) { 14.149 + vrm->rotation(eye, quat); 14.150 + return 1; 14.151 + } 14.152 + quat[0] = quat[1] = quat[2] = 0.0f; 14.153 + quat[3] = 1.0f; 14.154 + return 0; 14.155 +} 14.156 + 14.157 +int vr_view_matrix(int eye, float *mat) 14.158 +{ 14.159 + int have_trans, have_rot; 14.160 + float offs[3], quat[4]; 14.161 + float rmat[16], tmat[16]; 14.162 + 14.163 + if(vrm && vrm->view_matrix) { 14.164 + vrm->view_matrix(eye, mat); 14.165 + return 1; 14.166 + } 14.167 + 14.168 + have_trans = vr_view_translation(eye, offs); 14.169 + have_rot = vr_view_rotation(eye, quat); 14.170 + 14.171 + if(!have_trans && !have_rot) { 14.172 + return 0; 14.173 + } 14.174 + 14.175 + offs[0] = -offs[0]; 14.176 + offs[1] = -offs[1]; 14.177 + offs[2] = -offs[2]; 14.178 + 14.179 + translation_matrix(offs, tmat); 14.180 + rotation_matrix(quat, rmat); 14.181 + mult_matrix(mat, tmat, rmat); 14.182 + return 1; 14.183 +} 14.184 + 14.185 +int vr_proj_matrix(int eye, float znear, float zfar, float *mat) 14.186 +{ 14.187 + if(vrm && vrm->proj_matrix) { 14.188 + vrm->proj_matrix(eye, znear, zfar, mat); 14.189 + return 1; 14.190 + } 14.191 + memcpy(mat, idmat, sizeof idmat); 14.192 + return 0; 14.193 +} 14.194 + 14.195 +void vr_begin(int eye) 14.196 +{ 14.197 + if(vrm && vrm->begin) { 14.198 + vrm->begin(eye); 14.199 + } 14.200 +} 14.201 + 14.202 +void vr_end(void) 14.203 +{ 14.204 + if(vrm && vrm->end) { 14.205 + vrm->end(); 14.206 + } 14.207 +} 14.208 + 14.209 +int vr_swap_buffers(void) 14.210 +{ 14.211 + int res = 0; 14.212 + 14.213 + if(vrm && vrm->present) { 14.214 + res = vrm->present(); 14.215 + } 14.216 + 14.217 + if(!res) { 14.218 + swap_buffers(); 14.219 + } 14.220 + return 0; 14.221 +} 14.222 + 14.223 +void vr_output_texture(unsigned int tex, float umin, float vmin, float umax, float vmax) 14.224 +{ 14.225 + float halfu = (umax + umin) * 0.5f; 14.226 + 14.227 + vr_output_texture_eye(VR_EYE_LEFT, tex, umin, vmin, halfu, vmax); 14.228 + vr_output_texture_eye(VR_EYE_RIGHT, tex, halfu, vmin, umax, vmax); 14.229 +} 14.230 + 14.231 +void vr_output_texture_eye(int eye, unsigned int tex, float umin, float vmin, float umax, float vmax) 14.232 +{ 14.233 + if(vrm && vrm->set_eye_texture) { 14.234 + vrm->set_eye_texture(eye, tex, umin, vmin, umax, vmax); 14.235 + } 14.236 +} 14.237 + 14.238 +void vr_recenter(void) 14.239 +{ 14.240 + if(vrm && vrm->recenter) { 14.241 + vrm->recenter(); 14.242 + } 14.243 +} 14.244 + 14.245 + 14.246 +#ifdef __unix__ 14.247 +#include <GL/glx.h> 14.248 + 14.249 +static void swap_buffers(void) 14.250 +{ 14.251 + glXSwapBuffers(glXGetCurrentDisplay(), glXGetCurrentDrawable()); 14.252 +} 14.253 + 14.254 +#endif 14.255 + 14.256 +#ifdef WIN32 14.257 +#include <windows.h> 14.258 + 14.259 +static void swap_buffers(void) 14.260 +{ 14.261 + SwapBuffers(wglGetCurrentDC()); 14.262 +} 14.263 +#endif
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/src/vr.h Fri Aug 29 03:45:25 2014 +0300 15.3 @@ -0,0 +1,61 @@ 15.4 +#ifndef VR_H_ 15.5 +#define VR_H_ 15.6 + 15.7 +#define VR_OPT_DISPLAY_WIDTH "display-xres" 15.8 +#define VR_OPT_DISPLAY_HEIGHT "display-yres" 15.9 +#define VR_OPT_LEYE_XRES "left-eye-xres" 15.10 +#define VR_OPT_LEYE_YRES "left-eye-yres" 15.11 +#define VR_OPT_REYE_XRES "right-eye-xres" 15.12 +#define VR_OPT_REYE_YRES "right-eye-yres" 15.13 +#define VR_OPT_EYE_HEIGHT "eye-height" 15.14 +#define VR_OPT_IPD "ipd" 15.15 +#define VR_OPT_WIN_XOFFS "win-xoffset" 15.16 +#define VR_OPT_WIN_YOFFS "win-yoffset" 15.17 + 15.18 +enum { 15.19 + VR_EYE_LEFT, 15.20 + VR_EYE_RIGHT 15.21 +}; 15.22 + 15.23 +#ifdef __cplusplus 15.24 +extern "C" { 15.25 +#endif 15.26 + 15.27 +int vr_init(void); 15.28 +void vr_shutdown(void); 15.29 + 15.30 +int vr_module_count(void); 15.31 +const char *vr_module_name(int idx); 15.32 + 15.33 +int vr_use_module(int idx); 15.34 +int vr_use_module_named(const char *name); 15.35 + 15.36 +void vr_set_opti(const char *optname, int val); 15.37 +void vr_set_optf(const char *optname, float val); 15.38 +int vr_get_opti(const char *optname); 15.39 +float vr_get_optf(const char *optname); 15.40 + 15.41 +int vr_view_translation(int eye, float *vec); 15.42 +int vr_view_rotation(int eye, float *quat); 15.43 + 15.44 +/* returns non-zero if the active vr module provides this kind of matrix 15.45 + * information, otherwise it returns zero, and sets mat to identity 15.46 + */ 15.47 +int vr_view_matrix(int eye, float *mat); 15.48 +int vr_proj_matrix(int eye, float znear, float zfar, float *mat); 15.49 + 15.50 +void vr_begin(int eye); 15.51 +void vr_end(void); 15.52 +int vr_swap_buffers(void); 15.53 + 15.54 +/* set the output texture or separate textures for each eye */ 15.55 +void vr_output_texture(unsigned int tex, float umin, float vmin, float umax, float vmax); 15.56 +void vr_output_texture_eye(int eye, unsigned int tex, float umin, float vmin, float umax, float vmax); 15.57 + 15.58 +void vr_recenter(void); 15.59 + 15.60 +#ifdef __cplusplus 15.61 +} 15.62 +#endif 15.63 + 15.64 +#endif /* VR_H_ */
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/src/vr_impl.h Fri Aug 29 03:45:25 2014 +0300 16.3 @@ -0,0 +1,44 @@ 16.4 +#ifndef VR_IMPL_H_ 16.5 +#define VR_IMPL_H_ 16.6 + 16.7 +#include "vr.h" 16.8 +#include "opt.h" 16.9 + 16.10 +struct vr_module { 16.11 + char *name; 16.12 + 16.13 + int (*init)(void); 16.14 + void (*cleanup)(void); 16.15 + 16.16 + int (*set_option)(const char *opt, enum opt_type type, void *valp); 16.17 + int (*get_option)(const char *opt, enum opt_type type, void *valp); 16.18 + 16.19 + void (*translation)(int eye, float *vec); 16.20 + void (*rotation)(int eye, float *quat); 16.21 + 16.22 + void (*view_matrix)(int eye, float *mat); 16.23 + void (*proj_matrix)(int eye, float znear, float zfar, float *mat); 16.24 + 16.25 + void (*begin)(int eye); 16.26 + void (*end)(void); 16.27 + int (*present)(void); 16.28 + 16.29 + void (*set_eye_texture)(int eye, unsigned int tex, float umin, float vmin, float umax, float vmax); 16.30 + 16.31 + void (*recenter)(void); 16.32 +}; 16.33 + 16.34 +void vr_init_modules(void); 16.35 + 16.36 +void vr_clear_modules(void); 16.37 +void vr_register_module(struct vr_module *mod); 16.38 + 16.39 +int vr_get_num_modules(void); 16.40 +struct vr_module *vr_get_module(int idx); 16.41 + 16.42 +void vr_activate_module(int idx); 16.43 + 16.44 +int vr_get_num_active_modules(void); 16.45 +struct vr_module *vr_get_active_module(int idx); 16.46 + 16.47 +#endif /* VR_IMPL_H_ */
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/src/vr_libovr.c Fri Aug 29 03:45:25 2014 +0300 17.3 @@ -0,0 +1,308 @@ 17.4 +#ifdef WIN32 17.5 +#define OVR_OS_WIN32 17.6 +#endif 17.7 + 17.8 +#include "vr_impl.h" 17.9 + 17.10 +#ifdef USE_LIBOVR 17.11 +#include <stdio.h> 17.12 +#include <stdlib.h> 17.13 +#include <assert.h> 17.14 +#include "opt.h" 17.15 + 17.16 +#include <OVR_CAPI.h> 17.17 +#include <OVR_CAPI_GL.h> 17.18 + 17.19 +#define DISABLE_RETARDED_HEALTH_WARNING 17.20 + 17.21 +/* just dropping the prototype here to avoid including CAPI_HSWDisplay.h */ 17.22 +OVR_EXPORT void ovrhmd_EnableHSWDisplaySDKRender(ovrHmd hmd, ovrBool enabled); 17.23 + 17.24 +static ovrHmd hmd; 17.25 +static void *optdb; 17.26 +static ovrEyeRenderDesc eye_render_desc[2]; 17.27 +static ovrSizei eye_res[2]; 17.28 +static ovrGLTexture eye_tex[2]; 17.29 +static ovrFovPort eye_fov[2]; 17.30 +static ovrPosef pose[2]; 17.31 +static int deferred_init_done; 17.32 + 17.33 +static int init(void) 17.34 +{ 17.35 + int i, num_hmds; 17.36 + 17.37 + if(!ovr_Initialize()) { 17.38 + return -1; 17.39 + } 17.40 + printf("initialized LibOVR %s\n", ovr_GetVersionString()); 17.41 + 17.42 + if(!(num_hmds = ovrHmd_Detect())) { 17.43 + ovr_Shutdown(); 17.44 + return -1; 17.45 + } 17.46 + printf("%d Oculus HMD(s) found\n", num_hmds); 17.47 + 17.48 + hmd = 0; 17.49 + for(i=0; i<num_hmds; i++) { 17.50 + ovrHmd h; 17.51 + if(!(h = ovrHmd_Create(i))) { 17.52 + break; 17.53 + } 17.54 + printf(" [%d]: %s - %s\n", i, h->Manufacturer, h->ProductName); 17.55 + 17.56 + if(!hmd) { 17.57 + hmd = h; 17.58 + } else { 17.59 + ovrHmd_Destroy(h); 17.60 + } 17.61 + } 17.62 + 17.63 + if(!hmd) { 17.64 + fprintf(stderr, "failed to initialize any Oculus HMDs\n"); 17.65 + return -1; 17.66 + } 17.67 + 17.68 + ovrHmd_ConfigureTracking(hmd, 0xffffffff, 0); 17.69 + 17.70 + eye_fov[0] = hmd->DefaultEyeFov[0]; 17.71 + eye_fov[1] = hmd->DefaultEyeFov[1]; 17.72 + 17.73 + eye_res[0] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left, eye_fov[0], 1.0); 17.74 + eye_res[1] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Right, eye_fov[1], 1.0); 17.75 + 17.76 + /* create the options database */ 17.77 + if((optdb = create_options())) { 17.78 + set_option_int(optdb, VR_OPT_DISPLAY_WIDTH, hmd->Resolution.w); 17.79 + set_option_int(optdb, VR_OPT_DISPLAY_HEIGHT, hmd->Resolution.h); 17.80 + set_option_int(optdb, VR_OPT_LEYE_XRES, eye_res[0].w); 17.81 + set_option_int(optdb, VR_OPT_LEYE_YRES, eye_res[0].h); 17.82 + set_option_int(optdb, VR_OPT_REYE_XRES, eye_res[1].w); 17.83 + set_option_int(optdb, VR_OPT_REYE_YRES, eye_res[1].h); 17.84 + set_option_float(optdb, VR_OPT_EYE_HEIGHT, ovrHmd_GetFloat(hmd, OVR_KEY_EYE_HEIGHT, OVR_DEFAULT_EYE_HEIGHT)); 17.85 + set_option_float(optdb, VR_OPT_IPD, ovrHmd_GetFloat(hmd, OVR_KEY_IPD, OVR_DEFAULT_IPD)); 17.86 + set_option_int(optdb, VR_OPT_WIN_XOFFS, hmd->WindowsPos.x); 17.87 + set_option_int(optdb, VR_OPT_WIN_YOFFS, hmd->WindowsPos.y); 17.88 + } 17.89 + 17.90 + deferred_init_done = 0; 17.91 + return 0; 17.92 +} 17.93 + 17.94 +static void deferred_init(void) 17.95 +{ 17.96 + union ovrGLConfig glcfg; 17.97 + unsigned int dcaps; 17.98 + void *win = 0; 17.99 + 17.100 + deferred_init_done = 1; 17.101 + 17.102 + memset(&glcfg, 0, sizeof glcfg); 17.103 + glcfg.OGL.Header.API = ovrRenderAPI_OpenGL; 17.104 + glcfg.OGL.Header.RTSize = hmd->Resolution; 17.105 + glcfg.OGL.Header.Multisample = 1; 17.106 +#ifdef WIN32 17.107 + win = GetActiveWindow(); 17.108 + /*glcfg.OGL.Window = win; 17.109 + glcfg.OGL.DC = wglGetCurrentDC(); 17.110 + assert(glcfg.OGL.Window); 17.111 + assert(glcfg.OGL.DC);*/ 17.112 +#endif 17.113 + 17.114 + if(!(hmd->HmdCaps & ovrHmdCap_ExtendDesktop)) { 17.115 + ovrHmd_AttachToWindow(hmd, win, 0, 0); 17.116 + printf("running in \"direct-to-rift\" mode\n"); 17.117 + } else { 17.118 + printf("running in \"extended desktop\" mode\n"); 17.119 + } 17.120 + ovrHmd_SetEnabledCaps(hmd, ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction); 17.121 + 17.122 + dcaps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette | ovrDistortionCap_TimeWarp | 17.123 + ovrDistortionCap_Overdrive | ovrDistortionCap_NoRestore; 17.124 + 17.125 + if(!ovrHmd_ConfigureRendering(hmd, &glcfg.Config, dcaps, eye_fov, eye_render_desc)) { 17.126 + fprintf(stderr, "failed to configure LibOVR distortion renderer\n"); 17.127 + } 17.128 + 17.129 +#ifdef DISABLE_RETARDED_HEALTH_WARNING 17.130 + ovrhmd_EnableHSWDisplaySDKRender(hmd, 0); 17.131 +#endif 17.132 +} 17.133 + 17.134 +static void cleanup(void) 17.135 +{ 17.136 + if(hmd) { 17.137 + ovrHmd_Destroy(hmd); 17.138 + ovr_Shutdown(); 17.139 + } 17.140 +} 17.141 + 17.142 +static int set_option(const char *opt, enum opt_type type, void *valp) 17.143 +{ 17.144 + switch(type) { 17.145 + case OTYPE_INT: 17.146 + set_option_int(optdb, opt, *(int*)valp); 17.147 + break; 17.148 + 17.149 + case OTYPE_FLOAT: 17.150 + set_option_float(optdb, opt, *(float*)valp); 17.151 + break; 17.152 + } 17.153 + return 0; 17.154 +} 17.155 + 17.156 +static int get_option(const char *opt, enum opt_type type, void *valp) 17.157 +{ 17.158 + switch(type) { 17.159 + case OTYPE_INT: 17.160 + return get_option_int(optdb, opt, valp); 17.161 + case OTYPE_FLOAT: 17.162 + return get_option_float(optdb, opt, valp); 17.163 + } 17.164 + return -1; 17.165 +} 17.166 + 17.167 +static int translation(int eye, float *vec) 17.168 +{ 17.169 + if(!hmd) { 17.170 + vec[0] = vec[1] = vec[2] = 0; 17.171 + return 0; 17.172 + } 17.173 + 17.174 + pose[eye] = ovrHmd_GetEyePose(hmd, eye == VR_EYE_LEFT ? ovrEye_Left : ovrEye_Right); 17.175 + vec[0] = pose[eye].Position.x + eye_render_desc[eye].ViewAdjust.x; 17.176 + vec[1] = pose[eye].Position.y + eye_render_desc[eye].ViewAdjust.y; 17.177 + vec[2] = pose[eye].Position.z + eye_render_desc[eye].ViewAdjust.z; 17.178 + 17.179 + return 1; 17.180 +} 17.181 + 17.182 +static int rotation(int eye, float *quat) 17.183 +{ 17.184 + if(!hmd) { 17.185 + quat[0] = quat[1] = quat[2] = 0.0f; 17.186 + quat[3] = 1.0f; 17.187 + return 0; 17.188 + } 17.189 + 17.190 + pose[eye] = ovrHmd_GetEyePose(hmd, eye == VR_EYE_LEFT ? ovrEye_Left : ovrEye_Right); 17.191 + quat[0] = pose[eye].Orientation.x; 17.192 + quat[1] = pose[eye].Orientation.y; 17.193 + quat[2] = pose[eye].Orientation.z; 17.194 + quat[3] = pose[eye].Orientation.w; 17.195 + return 1; 17.196 +} 17.197 + 17.198 +static const float idmat[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; 17.199 + 17.200 +static void proj_matrix(int eye, float znear, float zfar, float *mat) 17.201 +{ 17.202 + int i, j; 17.203 + ovrMatrix4f vmat; 17.204 + 17.205 + if(!hmd) { 17.206 + memcpy(mat, idmat, sizeof idmat); 17.207 + return; 17.208 + } 17.209 + 17.210 + vmat = ovrMatrix4f_Projection(eye_render_desc[eye].Fov, znear, zfar, 1); 17.211 + 17.212 + for(i=0; i<4; i++) { 17.213 + for(j=0; j<4; j++) { 17.214 + *mat++ = vmat.M[j][i]; 17.215 + } 17.216 + } 17.217 +} 17.218 + 17.219 +static int new_frame = 1; 17.220 + 17.221 +static void begin(int eye) 17.222 +{ 17.223 + if(!hmd) return; 17.224 + 17.225 + if(!deferred_init_done) { 17.226 + deferred_init(); 17.227 + } 17.228 + 17.229 + if(new_frame) { 17.230 + ovrHmd_BeginFrame(hmd, 0); 17.231 + new_frame = 0; 17.232 + } 17.233 +} 17.234 + 17.235 +static int present(void) 17.236 +{ 17.237 + if(!hmd) return 0; 17.238 + 17.239 + ovrHmd_EndFrame(hmd, pose, &eye_tex[0].Texture); 17.240 + new_frame = 1; 17.241 + 17.242 + return 1; 17.243 +} 17.244 + 17.245 +static void set_eye_texture(int eye, unsigned int tex, float umin, float vmin, float umax, float vmax) 17.246 +{ 17.247 + ovrSizei texsz; 17.248 + ovrRecti rect; 17.249 + 17.250 + glBindTexture(GL_TEXTURE_2D, tex); 17.251 + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &texsz.w); 17.252 + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &texsz.h); 17.253 + 17.254 + rect.Pos.x = (int)(umin * texsz.w); 17.255 + rect.Pos.y = (int)((vmin + 1.0 - vmax) * texsz.h); 17.256 + rect.Size.w = (int)((umax - umin) * texsz.w); 17.257 + rect.Size.h = (int)((vmax - vmin) * texsz.h); 17.258 + 17.259 + eye_tex[eye].OGL.Header.API = ovrRenderAPI_OpenGL; 17.260 + eye_tex[eye].OGL.Header.TextureSize = texsz; 17.261 + eye_tex[eye].OGL.Header.RenderViewport = rect; 17.262 + eye_tex[eye].OGL.TexId = tex; 17.263 +} 17.264 + 17.265 +static void recenter(void) 17.266 +{ 17.267 + if(hmd) { 17.268 + ovrHmd_RecenterPose(hmd); 17.269 + } 17.270 +} 17.271 + 17.272 +struct vr_module *vr_module_libovr(void) 17.273 +{ 17.274 + static struct vr_module m; 17.275 + 17.276 + if(!m.init) { 17.277 + m.name = "libovr"; 17.278 + m.init = init; 17.279 + m.cleanup = cleanup; 17.280 + m.set_option = set_option; 17.281 + m.get_option = get_option; 17.282 + m.translation = translation; 17.283 + m.rotation = rotation; 17.284 + m.proj_matrix = proj_matrix; 17.285 + m.begin = begin; 17.286 + m.present = present; 17.287 + m.set_eye_texture = set_eye_texture; 17.288 + m.recenter = recenter; 17.289 + } 17.290 + return &m; 17.291 +} 17.292 + 17.293 +#else /* no libovr */ 17.294 + 17.295 +static int init(void) 17.296 +{ 17.297 + return -1; 17.298 +} 17.299 + 17.300 +struct vr_module *vr_module_libovr(void) 17.301 +{ 17.302 + static struct vr_module m; 17.303 + 17.304 + if(!m.init) { 17.305 + m.name = "libovr"; 17.306 + m.init = init; 17.307 + } 17.308 + return &m; 17.309 +} 17.310 + 17.311 +#endif /* USE_LIBOVR */
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/src/vr_modules.c Fri Aug 29 03:45:25 2014 +0300 18.3 @@ -0,0 +1,94 @@ 18.4 +/* XXX this might become partly auto-generated in the future */ 18.5 +#include <stdio.h> 18.6 +#include <stdlib.h> 18.7 +#include "vr_impl.h" 18.8 + 18.9 +struct vr_module *vr_module_libovr(void); 18.10 +struct vr_module *vr_module_openhmd(void); 18.11 +struct vr_module *vr_module_null(void); 18.12 + 18.13 +static struct vr_module *modules; 18.14 +static int num_modules, modules_max_size; 18.15 + 18.16 +static int *active_modules; 18.17 +static int num_act_modules, act_modules_max_size; 18.18 + 18.19 + 18.20 +void vr_init_modules(void) 18.21 +{ 18.22 + struct vr_module *m; 18.23 + 18.24 + vr_clear_modules(); 18.25 + 18.26 + if((m = vr_module_libovr())) { 18.27 + vr_register_module(m); 18.28 + } 18.29 + 18.30 + if((m = vr_module_openhmd())) { 18.31 + vr_register_module(m); 18.32 + } 18.33 + 18.34 + if((m = vr_module_null())) { 18.35 + vr_register_module(m); 18.36 + } 18.37 +} 18.38 + 18.39 +void vr_clear_modules(void) 18.40 +{ 18.41 + free(modules); 18.42 + free(active_modules); 18.43 + modules = 0; 18.44 + num_modules = modules_max_size = 0; 18.45 + active_modules = 0; 18.46 + num_act_modules = act_modules_max_size = 0; 18.47 +} 18.48 + 18.49 +void vr_register_module(struct vr_module *mod) 18.50 +{ 18.51 + if(num_modules >= modules_max_size) { 18.52 + int newsz = modules_max_size ? modules_max_size * 2 : 2; 18.53 + struct vr_module *newmods = realloc(modules, newsz * sizeof *newmods); 18.54 + if(!newmods) { 18.55 + fprintf(stderr, "failed to resize modules array up to %d\n", newsz); 18.56 + return; 18.57 + } 18.58 + modules = newmods; 18.59 + modules_max_size = newsz; 18.60 + } 18.61 + modules[num_modules++] = *mod; 18.62 +} 18.63 + 18.64 +int vr_get_num_modules(void) 18.65 +{ 18.66 + return num_modules; 18.67 +} 18.68 + 18.69 +struct vr_module *vr_get_module(int idx) 18.70 +{ 18.71 + return modules + idx; 18.72 +} 18.73 + 18.74 +void vr_activate_module(int idx) 18.75 +{ 18.76 + if(num_act_modules >= act_modules_max_size) { 18.77 + int newsz = act_modules_max_size ? act_modules_max_size * 2 : 2; 18.78 + int *newact = realloc(active_modules, newsz * sizeof *newact); 18.79 + if(!newact) { 18.80 + fprintf(stderr, "failed to resize active modules array up to %d\n", newsz); 18.81 + return; 18.82 + } 18.83 + active_modules = newact; 18.84 + act_modules_max_size = newsz; 18.85 + } 18.86 + active_modules[num_act_modules++] = idx; 18.87 +} 18.88 + 18.89 +int vr_get_num_active_modules(void) 18.90 +{ 18.91 + return num_act_modules; 18.92 +} 18.93 + 18.94 +struct vr_module *vr_get_active_module(int idx) 18.95 +{ 18.96 + return modules + active_modules[idx]; 18.97 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/src/vr_null.c Fri Aug 29 03:45:25 2014 +0300 19.3 @@ -0,0 +1,85 @@ 19.4 +#ifdef WIN32 19.5 +#define WIN32_LEAN_AND_MEAN 19.6 +#include <windows.h> 19.7 +#endif 19.8 +#ifdef __APPLE__ 19.9 +#include <OpenGL/gl.h> 19.10 +#else 19.11 +#include <GL/gl.h> 19.12 +#endif 19.13 +#include "vr_impl.h" 19.14 + 19.15 +static unsigned int eye_tex[2]; 19.16 +static float tex_umin[2], tex_umax[2]; 19.17 +static float tex_vmin[2], tex_vmax[2]; 19.18 + 19.19 +static int init(void) 19.20 +{ 19.21 + return 0; 19.22 +} 19.23 + 19.24 +static int present(void) 19.25 +{ 19.26 + int i; 19.27 + 19.28 + glPushAttrib(GL_ENABLE_BIT | GL_TRANSFORM_BIT); 19.29 + 19.30 + glDisable(GL_LIGHTING); 19.31 + glDisable(GL_DEPTH_TEST); 19.32 + glDisable(GL_FOG); 19.33 + glDisable(GL_CULL_FACE); 19.34 + 19.35 + glEnable(GL_TEXTURE_2D); 19.36 + 19.37 + glMatrixMode(GL_MODELVIEW); 19.38 + glLoadIdentity(); 19.39 + glMatrixMode(GL_PROJECTION); 19.40 + glLoadIdentity(); 19.41 + 19.42 + for(i=0; i<2; i++) { 19.43 + float x0 = i == 0 ? -1 : 0; 19.44 + float x1 = i == 0 ? 0 : 1; 19.45 + 19.46 + glBindTexture(GL_TEXTURE_2D, eye_tex[i]); 19.47 + 19.48 + glBegin(GL_QUADS); 19.49 + glTexCoord2f(tex_umin[i], tex_vmin[i]); 19.50 + glVertex2f(x0, -1); 19.51 + glTexCoord2f(tex_umax[i], tex_vmin[i]); 19.52 + glVertex2f(x1, -1); 19.53 + glTexCoord2f(tex_umax[i], tex_vmax[i]); 19.54 + glVertex2f(x1, 1); 19.55 + glTexCoord2f(tex_umin[i], tex_vmax[i]); 19.56 + glVertex2f(x0, 1); 19.57 + glEnd(); 19.58 + } 19.59 + 19.60 + glPopMatrix(); 19.61 + glMatrixMode(GL_MODELVIEW); 19.62 + glPopMatrix(); 19.63 + 19.64 + glPopAttrib(); 19.65 + return 0; 19.66 +} 19.67 + 19.68 +static void set_eye_texture(int eye, unsigned int tex, float umin, float vmin, float umax, float vmax) 19.69 +{ 19.70 + eye_tex[eye] = tex; 19.71 + tex_umin[eye] = umin; 19.72 + tex_umax[eye] = umax; 19.73 + tex_vmin[eye] = vmin; 19.74 + tex_vmax[eye] = vmax; 19.75 +} 19.76 + 19.77 +struct vr_module *vr_module_null(void) 19.78 +{ 19.79 + static struct vr_module m; 19.80 + 19.81 + if(!m.init) { 19.82 + m.name = "null"; 19.83 + m.init = init; 19.84 + m.set_eye_texture = set_eye_texture; 19.85 + m.present = present; 19.86 + } 19.87 + return &m; 19.88 +}
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/src/vr_openhmd.c Fri Aug 29 03:45:25 2014 +0300 20.3 @@ -0,0 +1,210 @@ 20.4 +#include "vr_impl.h" 20.5 + 20.6 +#ifdef USE_OPENHMD 20.7 +#include <stdio.h> 20.8 +#include <stdlib.h> 20.9 +#include <openhmd/openhmd.h> 20.10 +#include "opt.h" 20.11 + 20.12 +/* a noble spirit embiggens the framebuffer to avoid aliasing in the middle */ 20.13 +#define EMBIGGEN 1.5 20.14 + 20.15 +static ohmd_context *ctx; 20.16 +static ohmd_device *dev; 20.17 +static void *optdb; 20.18 +static int new_frame = 1; 20.19 + 20.20 +static int disp_width, disp_height; 20.21 +static float ipd; 20.22 + 20.23 +static struct { 20.24 + unsigned int id; 20.25 + float umin, umax; 20.26 + float vmin, vmax; 20.27 +} eye_tex[2]; 20.28 + 20.29 + 20.30 +static int init(void) 20.31 +{ 20.32 + int i, num_hmds; 20.33 + 20.34 + if(!(ctx = ohmd_ctx_create())) { 20.35 + fprintf(stderr, "failed to create OpenHMD context\n"); 20.36 + ohmd_ctx_destroy(ctx); 20.37 + return -1; 20.38 + } 20.39 + if(!(num_hmds = ohmd_ctx_probe(ctx))) { 20.40 + fprintf(stderr, "no HMDs detected\n"); 20.41 + return -1; 20.42 + } 20.43 + 20.44 + for(i=0; i<num_hmds; i++) { 20.45 + const char *vendor = ohmd_list_gets(ctx, i, OHMD_VENDOR); 20.46 + const char *product = ohmd_list_gets(ctx, i, OHMD_PRODUCT); 20.47 + const char *devpath = ohmd_list_gets(ctx, i, OHMD_PATH); 20.48 + 20.49 + printf("[%d] %s - %s (path: %s)\n", i, vendor, product, devpath); 20.50 + } 20.51 + 20.52 + printf("opening device 0\n"); 20.53 + 20.54 + if(!(dev = ohmd_list_open_device(ctx, 0))) { 20.55 + fprintf(stderr, "failed to open device 0: %s\n", ohmd_ctx_get_error(ctx)); 20.56 + return -1; 20.57 + } 20.58 + 20.59 + ohmd_device_geti(dev, OHMD_SCREEN_HORIZONTAL_SIZE, &disp_width); 20.60 + ohmd_device_geti(dev, OHMD_SCREEN_VERTICAL_SIZE, &disp_height); 20.61 + ohmd_device_getf(dev, OHMD_EYE_IPD, &ipd); 20.62 + 20.63 + if((optdb = create_options())) { 20.64 + set_option_int(optdb, VR_OPT_DISPLAY_WIDTH, disp_width); 20.65 + set_option_int(optdb, VR_OPT_DISPLAY_HEIGHT, disp_height); 20.66 + set_option_float(optdb, VR_OPT_IPD, ipd); 20.67 + 20.68 + set_option_int(optdb, VR_OPT_LEYE_XRES, (int)(disp_width / 2.0 * FB_EMBIGGEN)); 20.69 + set_option_int(optdb, VR_OPT_LEYE_YRES, (int)(disp_height * FB_EMBIGGEN)); 20.70 + set_option_int(optdb, VR_OPT_REYE_XRES, (int)(disp_width / 2.0 * FB_EMBIGGEN)); 20.71 + set_option_int(optdb, VR_OPT_REYE_YRES, (int)(disp_height * FB_EMBIGGEN)); 20.72 + } 20.73 + 20.74 + return 0; 20.75 +} 20.76 + 20.77 +static void cleanup(void) 20.78 +{ 20.79 + if(ctx) { 20.80 + ohmd_ctx_destroy(ctx); 20.81 + } 20.82 +} 20.83 + 20.84 + 20.85 +static int set_option(const char *opt, enum opt_type type, void *valp) 20.86 +{ 20.87 + switch(type) { 20.88 + case OTYPE_INT: 20.89 + set_option_int(optdb, opt, *(int*)valp); 20.90 + break; 20.91 + 20.92 + case OTYPE_FLOAT: 20.93 + set_option_float(optdb, opt, *(float*)valp); 20.94 + break; 20.95 + } 20.96 + return 0; 20.97 +} 20.98 + 20.99 +static int get_option(const char *opt, enum opt_type type, void *valp) 20.100 +{ 20.101 + switch(type) { 20.102 + case OTYPE_INT: 20.103 + return get_option_int(optdb, opt, valp); 20.104 + case OTYPE_FLOAT: 20.105 + return get_option_float(optdb, opt, valp); 20.106 + } 20.107 + return -1; 20.108 +} 20.109 + 20.110 +static int translation(int eye, float *vec) 20.111 +{ 20.112 + float xform[16]; 20.113 + 20.114 + view_matrix(eye, xform); 20.115 + 20.116 + vec[0] = xform[3]; 20.117 + vec[1] = xform[7]; 20.118 + vec[2] = xform[11]; 20.119 + return 0; 20.120 +} 20.121 + 20.122 +static int rotation(int eye, float *quat) 20.123 +{ 20.124 + if(!dev) { 20.125 + quat[0] = quat[1] = quat[2] = 0.0f; 20.126 + quat[3] = 1.0f; 20.127 + return -1; 20.128 + } 20.129 + 20.130 + ohmd_device_getf(dev, OHMD_ROTATION_QUAT, quat); 20.131 + return 0; 20.132 +} 20.133 + 20.134 + 20.135 +static void view_matrix(int eye, float *mat) 20.136 +{ 20.137 + ohmd_device_getf(dev, OHMD_LEFT_EYE_GL_MODELVIEW_MATRIX + eye, mat); 20.138 +} 20.139 + 20.140 +static void proj_matrix(int eye, float znear, float zfar, float *mat) 20.141 +{ 20.142 + ohmd_device_setf(dev, OHMD_PROJECTION_ZNEAR, znear); 20.143 + ohmd_device_setf(dev, OHMD_PROJECTION_ZFAR, zfar); 20.144 + ohmd_device_getf(dev, OHMD_LEFT_EYE_GL_PROJECTION_MATRIX + eye, mat); 20.145 +} 20.146 + 20.147 +static void begin(int eye) 20.148 +{ 20.149 + if(new_frame) { 20.150 + ohmd_ctx_update(ctx); 20.151 + new_frame = 0; 20.152 + } 20.153 +} 20.154 + 20.155 +static int present(void) 20.156 +{ 20.157 + new_frame = 1; 20.158 + return 0; 20.159 +} 20.160 + 20.161 +static void set_eye_texture(int eye, unsigned int tex, float umin, float vmin, float umax, float vmax) 20.162 +{ 20.163 + eye_tex[eye].id = tex; 20.164 + eye_tex[eye].umin = umin; 20.165 + eye_tex[eye].umax = umax; 20.166 + eye_tex[eye].vmin = vmin; 20.167 + eye_tex[eye].vmax = vmax; 20.168 +} 20.169 + 20.170 +static void recenter(void) 20.171 +{ 20.172 + /* TODO does OHMD support the magnetometer? */ 20.173 +} 20.174 + 20.175 + 20.176 +struct vr_module *vr_module_openhmd(void) 20.177 +{ 20.178 + static struct vr_module m; 20.179 + 20.180 + if(!m.init) { 20.181 + m.name = "openhmd"; 20.182 + m.init = init; 20.183 + m.cleanup = cleanup; 20.184 + m.set_option = set_option; 20.185 + m.get_option = get_option; 20.186 + m.view_matrix = view_matrix; 20.187 + m.proj_matrix = proj_matrix; 20.188 + m.begin = begin; 20.189 + m.present = present; 20.190 + m.set_eye_texture = set_eye_texture; 20.191 + m.recenter = recenter; 20.192 + } 20.193 +} 20.194 + 20.195 +#else /* don't use OpenHMD */ 20.196 + 20.197 +static int init(void) 20.198 +{ 20.199 + return -1; 20.200 +} 20.201 + 20.202 +struct vr_module *vr_module_openhmd(void) 20.203 +{ 20.204 + static struct vr_module m; 20.205 + 20.206 + if(!m.init) { 20.207 + m.name = "openhmd"; 20.208 + m.init = init; 20.209 + } 20.210 + return &m; 20.211 +} 20.212 + 20.213 +#endif /* USE_OPENHMD */