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 */